http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54293

--- Comment #6 from Jiří Paleček <jpalecek at web dot de> 2012-08-20 21:56:39 
UTC ---
(In reply to comment #5)
> I think there is a compiler bug.  The ruling text seems to be the
> first bullet of 8.5.3/5 and its first sub-bullet:
> 
>     - If the reference is an lvalue reference and the initializer
>       expression
> 
>        - is an lvalue (but is not a bit-field), and "cv1 T1" is
>          reference-compatible with "cv2 T2," or
> 
> which matches the expression in the test case:
> 
>    const int& ref_int = ValueHolder<int>().v;

The initializer is NOT an lvalue. ValueHolder<int>() is a class (p)rvalue, and
rvalue.something is still an rvalue, cf. 5.2.5/4, the second bullet applies:

— If E2 is a non-static data member and the type of E1 is “cq1 vq1 X”, and the
type of E2 is “cq2 vq2
T”, the expression designates the named member of the object designated by the
first expression. If
E1 is an lvalue, then E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an
xvalue; otherwise, it is a
prvalue. [ IMHO it misses the case when T is a reference type, but that doesn't
apply here ]

Therefore, I think the binding should proceed by the last case (because the
initializer expression is not a *class* (don't ask me why, but it is in the
standard text) prvalue, the first sub-bullet of the second bullet doesn't apply
either; only the second sub-bullet is left). In that case, you don't bind to
the ValueHolder temporary at all, so you don't extend its lifetime.

BTW you never extend the lifetime of anything when you bind according to the
first bullet of 8.5.3/5, because lvalues either don't trace to their object,
even if they were obtained from a temporary, so it would be impossible to do;
or they are named variables whose lifetime is simply not extended.

Reply via email to