From: Richard Smith Date: Thu, 27 Jun 2013 21:43:17 +0000 (+0000) Subject: Remove bogus VarDecl::extendsLifetimeOfTemporary function and inline it into X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=49bab4c0046e8300c79e79b7ca9a479696c7e87a;p=clang Remove bogus VarDecl::extendsLifetimeOfTemporary function and inline it into its only caller with a FIXME explaining why it's bogus. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185109 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 2eaf8d3a7f..8342f79f4e 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1019,20 +1019,6 @@ public: 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 diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index adba897bb5..5267789643 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1928,19 +1928,6 @@ bool VarDecl::checkInitIsICE() const { 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(E)) - E = Cleanups->getSubExpr(); - - return isa(E); -} - VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) return cast(MSI->getInstantiatedFrom()); diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 14b8fd4a10..695440c9cb 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -974,10 +974,23 @@ LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD, // 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(Init)) + Init = EWC->getSubExpr(); + if (!isa(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.