Author: tzik Date: Mon Jun 18 22:35:30 2018 New Revision: 335022 URL: http://llvm.org/viewvc/llvm-project?rev=335022&view=rev Log: Revert r335019 "Update NRVO logic to support early return (Attempt 2)"
Removed: cfe/trunk/test/CodeGenCXX/nrvo-noopt.cpp cfe/trunk/test/SemaCXX/nrvo-ast.cpp Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/Sema/Scope.h cfe/trunk/lib/Sema/Scope.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaStmt.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp cfe/trunk/test/CodeGenCXX/nrvo.cpp Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Mon Jun 18 22:35:30 2018 @@ -879,12 +879,6 @@ protected: DAK_Normal }; - enum NRVOMode { - NRVO_Candidate, - NRVO_Disabled, - NRVO_Enabled, - }; - class ParmVarDeclBitfields { friend class ASTDeclReader; friend class ParmVarDecl; @@ -937,7 +931,7 @@ protected: /// Whether this local variable could be allocated in the return /// slot of its function, enabling the named return value optimization /// (NRVO). - unsigned NRVOMode : 2; + unsigned NRVOVariable : 1; /// Whether this variable is the for-range-declaration in a C++0x /// for-range statement. @@ -1325,20 +1319,12 @@ public: /// return slot when returning from the function. Within the function body, /// each return that returns the NRVO object will have this variable as its /// NRVO candidate. - NRVOMode getNRVOMode() const { - if (isa<ParmVarDecl>(this)) - return NRVO_Disabled; - return static_cast<NRVOMode>(NonParmVarDeclBits.NRVOMode); - } - bool isNRVOCandidate() const { - return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOMode == NRVO_Candidate; - } bool isNRVOVariable() const { - return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOMode == NRVO_Enabled; + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOVariable; } void setNRVOVariable(bool NRVO) { assert(!isa<ParmVarDecl>(this)); - NonParmVarDeclBits.NRVOMode = NRVO ? NRVO_Enabled : NRVO_Disabled; + NonParmVarDeclBits.NRVOVariable = NRVO; } /// Determine whether this variable is the for-range-declaration in Modified: cfe/trunk/include/clang/Sema/Scope.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Scope.h (original) +++ cfe/trunk/include/clang/Sema/Scope.h Mon Jun 18 22:35:30 2018 @@ -201,6 +201,10 @@ private: /// Used to determine if errors occurred in this scope. DiagnosticErrorTrap ErrorTrap; + /// A lattice consisting of undefined, a single NRVO candidate variable in + /// this scope, or over-defined. The bit is true when over-defined. + llvm::PointerIntPair<VarDecl *, 1, bool> NRVO; + void setFlags(Scope *Parent, unsigned F); public: @@ -462,7 +466,23 @@ public: UsingDirectives.end()); } - void setNRVOCandidate(VarDecl *Candidate); + void addNRVOCandidate(VarDecl *VD) { + if (NRVO.getInt()) + return; + if (NRVO.getPointer() == nullptr) { + NRVO.setPointer(VD); + return; + } + if (NRVO.getPointer() != VD) + setNoNRVO(); + } + + void setNoNRVO() { + NRVO.setInt(true); + NRVO.setPointer(nullptr); + } + + void mergeNRVOIntoParent(); /// Init - This is used by the parser to implement scope caching. void Init(Scope *parent, unsigned flags); Modified: cfe/trunk/lib/Sema/Scope.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Scope.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Scope.cpp (original) +++ cfe/trunk/lib/Sema/Scope.cpp Mon Jun 18 22:35:30 2018 @@ -92,6 +92,7 @@ void Scope::Init(Scope *parent, unsigned UsingDirectives.clear(); Entity = nullptr; ErrorTrap.reset(); + NRVO.setPointerAndInt(nullptr, 0); } bool Scope::containedInPrototypeScope() const { @@ -118,15 +119,19 @@ void Scope::AddFlags(unsigned FlagsToSet Flags |= FlagsToSet; } -void Scope::setNRVOCandidate(VarDecl *Candidate) { - for (Decl *D : DeclsInScope) { - VarDecl *VD = dyn_cast<VarDecl>(D); - if (VD && VD != Candidate && VD->isNRVOCandidate()) - VD->setNRVOVariable(false); +void Scope::mergeNRVOIntoParent() { + if (VarDecl *Candidate = NRVO.getPointer()) { + if (isDeclScope(Candidate)) + Candidate->setNRVOVariable(true); } - if (Scope *parent = getParent()) - parent->setNRVOCandidate(Candidate); + if (getEntity()) + return; + + if (NRVO.getInt()) + getParent()->setNoNRVO(); + else if (NRVO.getPointer()) + getParent()->addNRVOCandidate(NRVO.getPointer()); } LLVM_DUMP_METHOD void Scope::dump() const { dumpImpl(llvm::errs()); } @@ -186,4 +191,9 @@ void Scope::dumpImpl(raw_ostream &OS) co OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n'; if (const DeclContext *DC = getEntity()) OS << "Entity : (clang::DeclContext*)" << DC << '\n'; + + if (NRVO.getInt()) + OS << "NRVO not allowed\n"; + else if (NRVO.getPointer()) + OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n'; } Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jun 18 22:35:30 2018 @@ -1798,6 +1798,8 @@ static void CheckPoppedLabel(LabelDecl * } void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { + S->mergeNRVOIntoParent(); + if (S->decl_empty()) return; assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && "Scope shouldn't contain decls!"); @@ -12561,24 +12563,21 @@ Decl *Sema::ActOnStartOfFunctionDef(Scop /// optimization. /// /// Each of the variables that is subject to the named return value -/// optimization will be marked as NRVO variable candidates in the AST, and any +/// optimization will be marked as NRVO variables in the AST, and any /// return statement that has a marked NRVO variable as its NRVO candidate can /// use the named return value optimization. /// -/// This function applies a very simplistic algorithm for NRVO: if every -/// reachable return statement in the scope of a variable has the same NRVO -/// candidate, that candidate is an NRVO variable. +/// This function applies a very simplistic algorithm for NRVO: if every return +/// statement in the scope of a variable has the same NRVO candidate, that +/// candidate is an NRVO variable. void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { - for (ReturnStmt *Return : Scope->Returns) { - const VarDecl *Candidate = Return->getNRVOCandidate(); - if (!Candidate) - continue; + ReturnStmt **Returns = Scope->Returns.data(); - if (Candidate->isNRVOCandidate()) - const_cast<VarDecl*>(Candidate)->setNRVOVariable(true); - - if (!Candidate->isNRVOVariable()) - Return->setNRVOCandidate(nullptr); + for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) { + if (const VarDecl *NRVOCandidate = Returns[I]->getNRVOCandidate()) { + if (!NRVOCandidate->isNRVOVariable()) + Returns[I]->setNRVOCandidate(nullptr); + } } } @@ -12713,8 +12712,12 @@ Decl *Sema::ActOnFinishFunctionBody(Decl else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(FD)) MarkVTableUsed(FD->getLocation(), Destructor->getParent()); - // Try to apply the named return value optimization. - computeNRVO(Body, getCurFunction()); + // Try to apply the named return value optimization. We have to check + // if we can do this here because lambdas keep return statements around + // to deduce an implicit return type. + if (FD->getReturnType()->isRecordType() && + (!getLangOpts().CPlusPlus || !FD->isDependentContext())) + computeNRVO(Body, getCurFunction()); } // GNU warning -Wmissing-prototypes: Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun 18 22:35:30 2018 @@ -13385,9 +13385,13 @@ ExprResult Sema::ActOnBlockStmtExpr(Sour if (Body && getCurFunction()->HasPotentialAvailabilityViolations) DiagnoseUnguardedAvailabilityViolations(BSI->TheDecl); - // Try to apply the named return value optimization. - computeNRVO(Body, BSI); - + // Try to apply the named return value optimization. We have to check again + // if we can do this, though, because blocks keep return statements around + // to deduce an implicit return type. + if (getLangOpts().CPlusPlus && RetTy->isRecordType() && + !BSI->TheDecl->isDependentContext()) + computeNRVO(Body, BSI); + BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result); Modified: cfe/trunk/lib/Sema/SemaStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) +++ cfe/trunk/lib/Sema/SemaStmt.cpp Mon Jun 18 22:35:30 2018 @@ -3455,9 +3455,12 @@ Sema::ActOnReturnStmt(SourceLocation Ret ExpressionEvaluationContext::DiscardedStatement) return R; - VarDecl *VD = - const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate()); - CurScope->setNRVOCandidate(VD); + if (VarDecl *VD = + const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate())) { + CurScope->addNRVOCandidate(VD); + } else { + CurScope->setNoNRVO(); + } CheckJumpOutOfSEHFinally(*this, ReturnLoc, *CurScope->getFnParent()); Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Jun 18 22:35:30 2018 @@ -740,13 +740,12 @@ Decl *TemplateDeclInstantiator::VisitVar SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner, StartingScope, InstantiatingVarTemplate); - bool NRVO = false; if (D->isNRVOVariable()) { QualType ReturnType = cast<FunctionDecl>(DC)->getReturnType(); if (SemaRef.isCopyElisionCandidate(ReturnType, Var, Sema::CES_Strict)) - NRVO = true; + Var->setNRVOVariable(true); } - Var->setNRVOVariable(NRVO); + Var->setImplicit(D->isImplicit()); return Var; Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Jun 18 22:35:30 2018 @@ -1326,7 +1326,7 @@ ASTDeclReader::RedeclarableResult ASTDec VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = Record.readInt(); VD->NonParmVarDeclBits.ExceptionVar = Record.readInt(); - VD->NonParmVarDeclBits.NRVOMode = Record.readInt(); + VD->NonParmVarDeclBits.NRVOVariable = Record.readInt(); VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt(); VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt(); VD->NonParmVarDeclBits.ARCPseudoStrong = Record.readInt(); Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Jun 18 22:35:30 2018 @@ -918,7 +918,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl if (!isa<ParmVarDecl>(D)) { Record.push_back(D->isThisDeclarationADemotedDefinition()); Record.push_back(D->isExceptionVariable()); - Record.push_back(D->getNRVOMode()); + Record.push_back(D->isNRVOVariable()); Record.push_back(D->isCXXForRangeDecl()); Record.push_back(D->isObjCForDecl()); Record.push_back(D->isARCPseudoStrong()); @@ -2031,7 +2031,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // NRVOMode + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isObjCForDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong Removed: cfe/trunk/test/CodeGenCXX/nrvo-noopt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nrvo-noopt.cpp?rev=335021&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/nrvo-noopt.cpp (original) +++ cfe/trunk/test/CodeGenCXX/nrvo-noopt.cpp (removed) @@ -1,58 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s - -struct X { - X(); - X(X&&); -}; - -// CHECK-LABEL: define void @_Z7test_00b -X test_00(bool b) { - if (b) { - // CHECK-NOT: call void @_ZN1XC1EOS_ - // CHECK: call void @_ZN1XC1Ev - // CHECK-NEXT: br label %return - X x; - return x; - } else { - // CHECK-NOT: call void @_ZN1XC1EOS_ - // CHECK: call void @_ZN1XC1Ev - // CHECK-NEXT: br label %return - X x; - return x; - } -} - -// CHECK-LABEL: define void @_Z7test_01b -X test_01(bool b) { - if (b) { - // CHECK-NOT: call void @_ZN1XC1EOS_ - // CHECK: call void @_ZN1XC1Ev - // CHECK-NEXT: br label %return - X x; - return x; - } - // CHECK-NOT: call void @_ZN1XC1EOS_ - // CHECK: call void @_ZN1XC1Ev - // CHECK-NEXT: br label %return - X x; - return x; -} - -// CHECK-LABEL: define void @_Z7test_02b -X test_02(bool b) { - // CHECK: call void @_ZN1XC1Ev - X x; - - if (b) { - // CHECK-NOT: call void @_ZN1XC1EOS_ - // CHECK: call void @_ZN1XC1Ev - // CHECK-NEXT: br label %return - X y; - return y; - } - - // CHECK-NOT: call void @_ZN1XC1Ev - // CHECK: call void @_ZN1XC1EOS_ - // CHECK-NEXT: br label %return - return x; -} Modified: cfe/trunk/test/CodeGenCXX/nrvo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nrvo.cpp?rev=335022&r1=335021&r2=335022&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/nrvo.cpp (original) +++ cfe/trunk/test/CodeGenCXX/nrvo.cpp Mon Jun 18 22:35:30 2018 @@ -130,13 +130,17 @@ X test2(bool B) { } // CHECK-LABEL: define void @_Z5test3b -X test3(bool B, X x) { +X test3(bool B) { // CHECK: tail call {{.*}} @_ZN1XC1Ev + // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_ + // CHECK: call {{.*}} @_ZN1XC1Ev + // CHECK: call {{.*}} @_ZN1XC1ERKS_ if (B) { X y; return y; } - // CHECK: tail call {{.*}} @_ZN1XC1ERKS_ + // FIXME: we should NRVO this variable too. + X x; return x; } @@ -187,13 +191,9 @@ X test6() { } // CHECK-LABEL: define void @_Z5test7b -// CHECK-EH-LABEL: define void @_Z5test7b X test7(bool b) { // CHECK: tail call {{.*}} @_ZN1XC1Ev // CHECK-NEXT: ret - - // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev - // CHECK-EH-NEXT: ret if (b) { X x; return x; @@ -202,14 +202,10 @@ X test7(bool b) { } // CHECK-LABEL: define void @_Z5test8b -// CHECK-EH-LABEL: define void @_Z5test8b X test8(bool b) { // CHECK: tail call {{.*}} @_ZN1XC1Ev // CHECK-NEXT: ret - - // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev - // CHECK-EH-NEXT: ret -if (b) { + if (b) { X x; return x; } else { @@ -225,37 +221,4 @@ Y<int> test9() { // CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv // CHECK: tail call {{.*}} @_ZN1YIiEC1Ev -// CHECK-LABEL: define void @_Z6test10b -X test10(bool B, X x) { - if (B) { - // CHECK: tail call {{.*}} @_ZN1XC1ERKS_ - // CHECK-EH: tail call {{.*}} @_ZN1XC1ERKS_ - return x; - } - // CHECK: tail call {{.*}} @_ZN1XC1Ev - // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_ - - // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev - // CHECK-EH-NOT: call {{.*}} @_ZN1XC1ERKS_ - X y; - return y; -} - -// CHECK-LABEL: define {{.*}} void @_Z6test11I1XET_v -// CHECK-EH-LABEL: define {{.*}} void @_Z6test11I1XET_v -template <typename T> -T test11() { - // CHECK: tail call {{.*}} @_ZN1XC1Ev - // CHECK-NEXT: ret void - - // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev - // CHECK-EH-NEXT: ret void - T t; - return t; -} - -void test12() { - test11<X>(); -} - // CHECK-EH-03: attributes [[NR_NUW]] = { noreturn nounwind } Removed: cfe/trunk/test/SemaCXX/nrvo-ast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nrvo-ast.cpp?rev=335021&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/nrvo-ast.cpp (original) +++ cfe/trunk/test/SemaCXX/nrvo-ast.cpp (removed) @@ -1,153 +0,0 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -ast-dump -o - %s | FileCheck %s - -struct X { - X(); - X(const X&); - X(X&&); -}; - -// CHECK-LABEL: FunctionDecl {{.*}} test_00 -X test_00() { - // CHECK: VarDecl {{.*}} x {{.*}} nrvo - X x; - return x; -} - -// CHECK-LABEL: FunctionDecl {{.*}} test_01 -X test_01(bool b) { - // CHECK: VarDecl {{.*}} x {{.*}} nrvo - X x; - if (b) - return x; - return x; -} - -// CHECK-LABEL: FunctionDecl {{.*}} test_02 -X test_02(bool b) { - // CHECK-NOT: VarDecl {{.*}} x {{.*}} nrvo - X x; - // CHECK-NOT: VarDecl {{.*}} y {{.*}} nrvo - X y; - if (b) - return y; - return x; -} - -// CHECK-LABEL: FunctionDecl {{.*}} test_03 -X test_03(bool b) { - if (b) { - // CHECK: VarDecl {{.*}} y {{.*}} nrvo - X y; - return y; - } - // CHECK: VarDecl {{.*}} x {{.*}} nrvo - X x; - return x; -} - -extern "C" _Noreturn void exit(int) throw(); - -// CHECK-LABEL: FunctionDecl {{.*}} test_04 -X test_04(bool b) { - { - // CHECK: VarDecl {{.*}} x {{.*}} nrvo - X x; - if (b) - return x; - } - exit(1); -} - -void may_throw(); -// CHECK-LABEL: FunctionDecl {{.*}} test_05 -X test_05() { - try { - may_throw(); - return X(); - } catch (X x) { - // CHECK-NOT: VarDecl {{.*}} x {{.*}} nrvo - return x; - } -} - -// CHECK-LABEL: FunctionDecl {{.*}} test_06 -X test_06() { - // CHECK-NOT: VarDecl {{.*}} x {{.*}} nrvo - X x __attribute__((aligned(8))); - return x; -} - -// CHECK-LABEL: FunctionDecl {{.*}} test_07 -X test_07(bool b) { - if (b) { - // CHECK: VarDecl {{.*}} x {{.*}} nrvo - X x; - return x; - } - return X(); -} - -// CHECK-LABEL: FunctionDecl {{.*}} test_08 -X test_08(bool b) { - if (b) { - // CHECK: VarDecl {{.*}} x {{.*}} nrvo - X x; - return x; - } else { - // CHECK: VarDecl {{.*}} y {{.*}} nrvo - X y; - return y; - } -} - -template <typename T> -struct Y { - Y(); - // CHECK-LABEL: CXXMethodDecl {{.*}} test_09 'Y<T> ()' - // CHECK: VarDecl {{.*}} y 'Y<T>' nrvo - - // CHECK-LABEL: CXXMethodDecl {{.*}} test_09 'Y<int> ()' - // CHECK: VarDecl {{.*}} y 'Y<int>' nrvo - static Y test_09() { - Y y; - return y; - } -}; - -struct Z { - Z(const X&); -}; - -// CHECK-LABEL: FunctionDecl {{.*}} test_10 'A ()' -// CHECK: VarDecl {{.*}} b 'B' nrvo - -// CHECK-LABEL: FunctionDecl {{.*}} test_10 'X ()' -// CHECK: VarDecl {{.*}} b {{.*}} nrvo - -// CHECK-LABEL: FunctionDecl {{.*}} test_10 'Z ()' -// CHECK-NOT: VarDecl {{.*}} b {{.*}} nrvo -template <typename A, typename B> -A test_10() { - B b; - return b; -} - -// CHECK-LABEL: FunctionDecl {{.*}} test_11 'A (bool)' -// CHECK-NOT: VarDecl {{.*}} a {{.*}} nrvo - -// CHECK-LABEL: FunctionDecl {{.*}} test_11 'X (bool)' -// CHECK-NOT: VarDecl {{.*}} a {{.*}} nrvo -template <typename A> -A test_11(bool b) { - A a; - if (b) - return A(); - return a; -} - -void instantiate() { - Y<int>::test_09(); - test_10<X, X>(); - test_10<Z, X>(); - test_11<X>(true); -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits