public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
@ 2012-08-16 22:28 ppluzhnikov at google dot com
  2012-08-16 23:02 ` [Bug c++/54293] " pinskia at gcc dot gnu.org
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: ppluzhnikov at google dot com @ 2012-08-16 22:28 UTC (permalink / raw)
  To: gcc-bugs

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

             Bug #: 54293
           Summary: When a reference is bound to subobject of a temporary,
                    lifetime of the temporary is not extended
    Classification: Unclassified
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: ppluzhnikov@google.com


Google reference: b/6996555

"ISO/IEC 14882:2011(E) 12.2.5 [class.temporary]

The temporary to which the reference is bound or the temporary that is the
complete object of a subobject to which the reference is bound persists for the
lifetime of the reference except: [etc]"

With gcc-4.6, the lifetime extension is not happening at all:

FAIL int
FAIL Obj

With gcc-4.7 and 4.8 (rev 190453), lifetime is extended for Obj subobject, but
not for 'int' (or 'char', or other primitive types):

FAIL int

The test:

#include <set>
#include <iostream>

std::set<const void*> subobjs;

template <typename T>
struct ValueHolder {
  explicit ValueHolder() {
    subobjs.insert(&v);
  }
  ~ValueHolder() {
    subobjs.erase(&v);
  }
  T v;
};

struct Obj { };

bool IsValid(const void* p) {
  return subobjs.find(p) != subobjs.end();
}

int main() {
  const int& ref_int = ValueHolder<int>().v;
  if (!IsValid(&ref_int)) {
    std::cout << "FAIL int" << std::endl;
  }

  const Obj& ref_obj = ValueHolder<Obj>().v;
  if (!IsValid(&ref_obj)) {
    std::cout << "FAIL Obj" << std::endl;
  }
}


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
@ 2012-08-16 23:02 ` pinskia at gcc dot gnu.org
  2012-08-16 23:07 ` ppluzhnikov at google dot com
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu.org @ 2012-08-16 23:02 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> 2012-08-16 23:02:07 UTC ---
I think this is a dup of bug 54197 or at least related to it.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
  2012-08-16 23:02 ` [Bug c++/54293] " pinskia at gcc dot gnu.org
@ 2012-08-16 23:07 ` ppluzhnikov at google dot com
  2012-08-17 14:19 ` aaw at gcc dot gnu.org
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: ppluzhnikov at google dot com @ 2012-08-16 23:07 UTC (permalink / raw)
  To: gcc-bugs

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

Paul Pluzhnikov <ppluzhnikov at google dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |aaw at gcc dot gnu.org

--- Comment #2 from Paul Pluzhnikov <ppluzhnikov at google dot com> 2012-08-16 23:06:58 UTC ---
(In reply to comment #1)
> I think this is a dup of bug 54197 or at least related to it.

Definitely not a dup. I somewhat doubt it's related.

Ollie, you have a GCC build with your patch for PR54197. Could you please check
what (if any) effect it has on this test case?


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
  2012-08-16 23:02 ` [Bug c++/54293] " pinskia at gcc dot gnu.org
  2012-08-16 23:07 ` ppluzhnikov at google dot com
@ 2012-08-17 14:19 ` aaw at gcc dot gnu.org
  2012-08-17 14:55 ` jpalecek at web dot de
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: aaw at gcc dot gnu.org @ 2012-08-17 14:19 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Ollie Wild <aaw at gcc dot gnu.org> 2012-08-17 14:18:59 UTC ---
No, this is a different failure.  With my patch applied, the testcase still
fails exactly as described.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (2 preceding siblings ...)
  2012-08-17 14:19 ` aaw at gcc dot gnu.org
@ 2012-08-17 14:55 ` jpalecek at web dot de
  2012-08-20 18:14 ` crowl at gcc dot gnu.org
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: jpalecek at web dot de @ 2012-08-17 14:55 UTC (permalink / raw)
  To: gcc-bugs

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

Jiří Paleček <jpalecek at web dot de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jpalecek at web dot de

--- Comment #4 from Jiří Paleček <jpalecek at web dot de> 2012-08-17 14:54:50 UTC ---
Is that even a bug? In the standard (8.5.3/5), there is:

— If the initializer expression
— is an xvalue, *class prvalue*, array prvalue or function lvalue and “cv1 T1”
is reference-
compatible with “cv2 T2”, or
— has a class type (i.e., T2 is a class type), where T1 is not
reference-related to T2, and can be
implicitly converted to an xvalue, class prvalue, or function lvalue of type
“cv3 T3”, where
“cv1 T1” is reference-compatible with “cv3 T3”,

I don't think an rvalue of type int (which you have there as the initializer)
is a class prvalue, so the initialization should proceed by the next stanza,
ie. creating a temporary of type int thereby not extending the lifetime of
ValueHolder temporary.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (3 preceding siblings ...)
  2012-08-17 14:55 ` jpalecek at web dot de
@ 2012-08-20 18:14 ` crowl at gcc dot gnu.org
  2012-08-20 21:56 ` jpalecek at web dot de
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: crowl at gcc dot gnu.org @ 2012-08-20 18:14 UTC (permalink / raw)
  To: gcc-bugs

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

crowl at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |crowl at gcc dot gnu.org

--- Comment #5 from crowl at gcc dot gnu.org 2012-08-20 18:14:32 UTC ---
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 lifetime is extended by 12.2/5 where none of the exceptions
apply.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (4 preceding siblings ...)
  2012-08-20 18:14 ` crowl at gcc dot gnu.org
@ 2012-08-20 21:56 ` jpalecek at web dot de
  2012-08-20 22:18 ` daniel.kruegler at googlemail dot com
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: jpalecek at web dot de @ 2012-08-20 21:56 UTC (permalink / raw)
  To: gcc-bugs

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.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (5 preceding siblings ...)
  2012-08-20 21:56 ` jpalecek at web dot de
@ 2012-08-20 22:18 ` daniel.kruegler at googlemail dot com
  2012-08-20 22:52 ` jpalecek at web dot de
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-08-20 22:18 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-08-20 22:17:45 UTC ---
(In reply to comment #6)
> — 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 ]

Did you mean E2 instead of T here? In this case this is described in the
beginning of 5.2.5 p4:

"If E2 is declared to have type “reference to T,” then E1.E2 is an lvalue; the
type of E1.E2 is T."

I agree with your analysis, but would like to point out that there is change
planned to essentially this part of the wording due to 

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#616

Assuming it becomes accepted E1.E2 will become an xvalue in this case (SE
bullet 2 of the P/R)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (6 preceding siblings ...)
  2012-08-20 22:18 ` daniel.kruegler at googlemail dot com
@ 2012-08-20 22:52 ` jpalecek at web dot de
  2012-08-21  6:14 ` daniel.kruegler at googlemail dot com
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: jpalecek at web dot de @ 2012-08-20 22:52 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Jiří Paleček <jpalecek at web dot de> 2012-08-20 22:52:31 UTC ---
(In reply to comment #7)
> (In reply to comment #6)
> > — 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 ]
> 
> Did you mean E2 instead of T here? In this case this is described in the
> beginning of 5.2.5 p4:
> 
> "If E2 is declared to have type “reference to T,” then E1.E2 is an lvalue; the
> type of E1.E2 is T."

You're right, my bad. I thought it MUST be there but missed that - anyway, it
is not relevant here.

> I agree with your analysis, but would like to point out that there is change
> planned to essentially this part of the wording due to 
> 
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#616
> 
> Assuming it becomes accepted E1.E2 will become an xvalue in this case (SE
> bullet 2 of the P/R)

Thanks for the info, it is interesting (although I can't see the relevance of
this particular change to the issues it should solve, which are basically about
using uninitialized objects).


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (7 preceding siblings ...)
  2012-08-20 22:52 ` jpalecek at web dot de
@ 2012-08-21  6:14 ` daniel.kruegler at googlemail dot com
  2012-08-21  7:52 ` jpalecek at web dot de
  2012-08-21  8:08 ` daniel.kruegler at googlemail dot com
  10 siblings, 0 replies; 12+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-08-21  6:14 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-08-21 06:13:50 UTC ---
(In reply to comment #8)
> > I agree with your analysis, but would like to point out that there is change
> > planned to essentially this part of the wording due to 
> > 
> > http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#616
> > 
> > Assuming it becomes accepted E1.E2 will become an xvalue in this case (SE
> > bullet 2 of the P/R)
> 
> Thanks for the info, it is interesting (although I can't see the relevance of
> this particular change to the issues it should solve, which are basically about
> using uninitialized objects).

Well, this addition *would* change the expected outcome. Because given the CWG
616 P/R the expression

ValueHolder<int>().v

becomes an xvalue (The special rule about class rvalues is no longer relevant
here), this means that the compiler shall *not* copy-initialize a temporary as
described in the very last bullet of 8.5.3/5.

In other words: In this case IsValid(&ref_int) will hold for the same reasons
as it holds for IsValid(&ref_obj).


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (8 preceding siblings ...)
  2012-08-21  6:14 ` daniel.kruegler at googlemail dot com
@ 2012-08-21  7:52 ` jpalecek at web dot de
  2012-08-21  8:08 ` daniel.kruegler at googlemail dot com
  10 siblings, 0 replies; 12+ messages in thread
From: jpalecek at web dot de @ 2012-08-21  7:52 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from Jiří Paleček <jpalecek at web dot de> 2012-08-21 07:51:55 UTC ---
(In reply to comment #9)
> (In reply to comment #8)
> > > I agree with your analysis, but would like to point out that there is change
> > > planned to essentially this part of the wording due to 
> > > 
> > > http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#616
> > > 
> > > Assuming it becomes accepted E1.E2 will become an xvalue in this case (SE
> > > bullet 2 of the P/R)
> > 
> > Thanks for the info, it is interesting (although I can't see the relevance of
> > this particular change to the issues it should solve, which are basically about
> > using uninitialized objects).
> 
> Well, this addition *would* change the expected outcome. Because given the CWG
> 616 P/R the expression
> 
> ValueHolder<int>().v
> 
> becomes an xvalue (The special rule about class rvalues is no longer relevant
> here), this means that the compiler shall *not* copy-initialize a temporary as
> described in the very last bullet of 8.5.3/5.
> 
> In other words: In this case IsValid(&ref_int) will hold for the same reasons
> as it holds for IsValid(&ref_obj).

That is true, and I didn't object that. I rather didn't understand how is that
particular change related to solving issues 616, 129, 240 and some others
mentioned there.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/54293] When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended
  2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
                   ` (9 preceding siblings ...)
  2012-08-21  7:52 ` jpalecek at web dot de
@ 2012-08-21  8:08 ` daniel.kruegler at googlemail dot com
  10 siblings, 0 replies; 12+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-08-21  8:08 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #11 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-08-21 08:07:28 UTC ---
(In reply to comment #10)
> > In other words: In this case IsValid(&ref_int) will hold for the same reasons
> > as it holds for IsValid(&ref_obj).
> 
> That is true, and I didn't object that. I rather didn't understand how is that
> particular change related to solving issues 616, 129, 240 and some others
> mentioned there.

Sorry, I misunderstood your comment. This particular 616 wording change was a
"side-step" change that was done as part of the issue (it was recognized while
discussing it), the drafting note during the Kona meeting says:

"Drafting note: This change addresses core issue 240, third item in a
minimally-intrusive way [..]"


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-08-21  8:08 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-16 22:28 [Bug c++/54293] New: When a reference is bound to subobject of a temporary, lifetime of the temporary is not extended ppluzhnikov at google dot com
2012-08-16 23:02 ` [Bug c++/54293] " pinskia at gcc dot gnu.org
2012-08-16 23:07 ` ppluzhnikov at google dot com
2012-08-17 14:19 ` aaw at gcc dot gnu.org
2012-08-17 14:55 ` jpalecek at web dot de
2012-08-20 18:14 ` crowl at gcc dot gnu.org
2012-08-20 21:56 ` jpalecek at web dot de
2012-08-20 22:18 ` daniel.kruegler at googlemail dot com
2012-08-20 22:52 ` jpalecek at web dot de
2012-08-21  6:14 ` daniel.kruegler at googlemail dot com
2012-08-21  7:52 ` jpalecek at web dot de
2012-08-21  8:08 ` daniel.kruegler at googlemail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).