From c117f224c622bac377d7fcf102ef6f29598099d8 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Sat, 26 Apr 2014 18:29:13 +0000 Subject: [PATCH] [Sema] Adjust Sema::getCurBlock()/getCurLambda() to take into account that we may have switch CurContext due to class template instantiation. Fixes crash of the included test case. rdar://16527205 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207325 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.cpp | 20 ++++++++++++++++++-- lib/Sema/SemaExpr.cpp | 2 +- lib/Sema/SemaLambda.cpp | 3 ++- test/SemaCXX/decltype.cpp | 21 +++++++++++++++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index a0d64ac2af..8faf29556e 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -1114,14 +1114,30 @@ BlockScopeInfo *Sema::getCurBlock() { if (FunctionScopes.empty()) return 0; - return dyn_cast(FunctionScopes.back()); + auto CurBSI = dyn_cast(FunctionScopes.back()); + if (CurBSI && CurBSI->TheDecl && + !CurBSI->TheDecl->Encloses(CurContext)) { + // We have switched contexts due to template instantiation. + assert(!ActiveTemplateInstantiations.empty()); + return nullptr; + } + + return CurBSI; } LambdaScopeInfo *Sema::getCurLambda() { if (FunctionScopes.empty()) return 0; - return dyn_cast(FunctionScopes.back()); + auto CurLSI = dyn_cast(FunctionScopes.back()); + if (CurLSI && CurLSI->Lambda && + !CurLSI->Lambda->Encloses(CurContext)) { + // We have switched contexts due to template instantiation. + assert(!ActiveTemplateInstantiations.empty()); + return nullptr; + } + + return CurLSI; } // We have a generic lambda if we parsed auto parameters, or we have // an associated template parameter list. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 1c6cfb8484..6d624adc4e 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10557,7 +10557,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, // to deduce an implicit return type. if (getLangOpts().CPlusPlus && RetTy->isRecordType() && !BSI->TheDecl->isDependentContext()) - computeNRVO(Body, getCurBlock()); + computeNRVO(Body, BSI); BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 0d287f7210..537f1ec8ab 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -1139,6 +1139,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, bool IsInstantiation) { + LambdaScopeInfo *LSI = getCurLambda(); + // Leave the expression-evaluation context. DiscardCleanupsInEvaluationContext(); PopExpressionEvaluationContext(); @@ -1148,7 +1150,6 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, PopDeclContext(); // Finalize the lambda. - LambdaScopeInfo *LSI = getCurLambda(); CXXRecordDecl *Class = LSI->Lambda; Class->setInvalidDecl(); SmallVector Fields(Class->fields()); diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp index 8de5a9c3ba..f1900b2b83 100644 --- a/test/SemaCXX/decltype.cpp +++ b/test/SemaCXX/decltype.cpp @@ -16,6 +16,27 @@ void test_f2() { float &fr = f2(AC().a); } +template +struct Future { + explicit Future(T v); + + template + auto call(F&& fn) -> decltype(fn(T())) { + return fn(T()); + } + + template + auto then(F&& fn) -> decltype(call(fn)) + { + return fn(T()); + } +}; + +void rdar16527205() { + Future f1(42); + f1.call([](int){ return Future(0); }); +} + namespace pr10154 { class A{ A(decltype(nullptr) param); -- 2.40.0