Repository navigation
C++: binding a reference to a temporary’s sub-object destroys the temporary too early #288
Momen-G-Ar
started this conversation in
Issue Triage - Standard Conformance
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Issue Summary
When a reference is bound to a subobject of a temporary, the lifetime of the whole temporary must be extended to the lifetime of the reference ([class.temporary]/6, C++20 6.7.7p6). In two cases the front end destroys the temporary at the end of the full-expression instead, and the reference dangles:
const int &r = A().b;in g++ and Clang modes (--g++,--clang). Strict--c++20is correct.const int &r = flag ? A().b : A().i[0];in all modes, including strict--c++20.A().i[0],A().*pmandint (&&r)[2] = A().i;work correctly in every mode I tried. g++ 15 and Clang extend the lifetime in all five cases.Reproducing Source Code
temp_lifetime_subobject.cpp
The file has no headers and is under 40 lines. Each line of output is one case; the exit status is the number of failures.
Command-line Options
eccp --c++20 --g++ --gnu_version=150000 temp_lifetime_subobject.cpp && ./a.out
Type of Issue
[Back End] There is a problem with the generated C code.
Additional Details
The code compiles; the generated program destroys the temporary too early. I picked "generated C code" because that is where the symptom shows, but the cause is in the front end (the value category of the expression), so no back end change is needed.
Output on
main(4e739c2):Expected:
okon every line, which is what g++ 15 and Clang produce.What I think causes it:
A().bshould be an xvalue (C++14 and later). In GNU and Clang modes the front end still treats it as a prvalue (the C++11 rule, kept in 2014 for compatibility; seesrc/Changes, 11/26/14). So the reference binds to a copy ofb, and only the copy's lifetime is extended. GCC 9 and Clang 4 implement Core issue 616.A().i[0], should give an xvalue, but the front end always gives an lvalue. The two operands of?:then have different value categories (xvalue and lvalue), so the conditional is a prvalue and is copied. GCC 9 and Clang 7 implement Core issue 1213.I have a small patch for both (about 30 lines in
src/cmd_line.c,src/expr.candsrc/exprutil.c, plus aChangesentry and a regression test) and can open a PR once there is an issue.Reproducing (Standard) Configuration(s)
linux-gcc-debug
Reproducing (Non-standard) Configuration
No response
I acknowledge that:
LICENSE.txtfile.All reactions