[cfe-commits] [patch] Bug 5077

Douglas Gregor dgregor at apple.com
Wed Nov 4 14:04:29 PST 2009

On Oct 15, 2009, at 10:22 PM, Dimitri Tcaciuc wrote:

> Douglas,
> Thanks for replying!
> On Mon, Oct 12, 2009 at 9:24 AM, Douglas Gregor <dgregor at apple.com>  
> wrote:
>>> * (?) There should be no meaningful temporaries left after member
>>> initializer completes.
>> Temporaries can live after the member initializer completes if they  
>> were
>> bound to a reference member (12.2p5). In this case, the temporaries  
>> are
>> destroyed at the end of the constructor.
> Ah, ok. Although that doesn't stop the reference from being invalid
> after constructor completes, does it?

No, it doesn't.

> Are we throwing a warning about
> it somewhere?

No, we don't have a warning for this. It would fit well with some kind  
of escape analysis for references or pointers to local variables.

> Hmm, so then we need to add a clean-up bit for those somewhere inside
> CodeGenFunction::GenerateCode after EmitStmt(S); and before
> FinishFunction(). I'm trying to think if we can safely assume that
> whatever temporaries are still left over at the end of constructor
> body before FinishFunction() are safe to discard. I remember that was
> the first incorrect fix for this bug that I tried.


> There's also the question about how to separate the reference bound
> temporaries from the rest. I'm looking at
> CodeGenFunction::EmitReferenceBindingToExpr, so I guess I can try
>  CXXBaseOrMemberInitializer::const_arg_iterator arg =
> Member->const_arg_begin();
>  if (const CXXBindTemporaryExpr* TE = dyn_cast< CXXBindTemporaryExpr  
> >(*E)) {
>    ...
>  }
> However, if I make the reference member const and initialize it with a
> non const, then the CXXBindTemporaryExpr is wrapped with  an
> ImplicitCastExpr and the above plan is foiled..
> Also, all live temporaries are on one stack... perhaps take the
> reference bound ones off the top, keep in a separate vector, then push
> back onto LiveTemporaries at the end of EmitCtorPrologue? Kind of
> hacky...

IIRC, there's existing code for extending the lifetime of a temporary  
when it is bound to a reference. I wasn't able to find it myself, but  
I'd bet that tracing through CodeGen for something like

   	struct X { /* ... */ };
	X make_an_X();
	const X& x = make_an_X();

would illustrate how to extend the life of the temporary to match with  
the lifetime of the value "x". The same approach should be reusable  
for extending the lifetime of temporaries bound to reference members.

	- Doug

More information about the cfe-commits mailing list