void setInit(Expr *I);
- /// \brief Determine whether this variable is a reference that
- /// extends the lifetime of its temporary initializer.
- ///
- /// A reference extends the lifetime of its temporary initializer if
- /// it's initializer is an rvalue that would normally go out of scope
- /// at the end of the initializer (a full expression). In such cases,
- /// the reference itself takes ownership of the temporary, which will
- /// be destroyed when the reference goes out of scope. For example:
- ///
- /// \code
- /// const int &r = 1.0; // creates a temporary of type 'int'
- /// \endcode
- bool extendsLifetimeOfTemporary() const;
-
/// \brief Determine whether this variable's value can be used in a
/// constant expression, according to the relevant language standard.
/// This only checks properties of the declaration, and does not check
return Eval->IsICE;
}
-bool VarDecl::extendsLifetimeOfTemporary() const {
- assert(getType()->isReferenceType() &&"Non-references never extend lifetime");
-
- const Expr *E = getInit();
- if (!E)
- return false;
-
- if (const ExprWithCleanups *Cleanups = dyn_cast<ExprWithCleanups>(E))
- E = Cleanups->getSubExpr();
-
- return isa<MaterializeTemporaryExpr>(E);
-}
-
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
return cast<VarDecl>(MSI->getInstantiatedFrom());
// Check for const references bound to temporary. Set type to pointee.
QualType QT = VD->getType();
if (QT.getTypePtr()->isReferenceType()) {
- if (!VD->extendsLifetimeOfTemporary())
+ // Attempt to determine whether this declaration lifetime-extends a
+ // temporary.
+ //
+ // FIXME: This is incorrect. Non-reference declarations can lifetime-extend
+ // temporaries, and a single declaration can extend multiple temporaries.
+ // We should look at the storage duration on each nested
+ // MaterializeTemporaryExpr instead.
+ const Expr *Init = VD->getInit();
+ if (!Init)
+ return Scope;
+ if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init))
+ Init = EWC->getSubExpr();
+ if (!isa<MaterializeTemporaryExpr>(Init))
return Scope;
- QT = getReferenceInitTemporaryType(*Context, VD->getInit());
+ // Lifetime-extending a temporary.
+ QT = getReferenceInitTemporaryType(*Context, Init);
}
// Check for constant size array. Set type to array element type.