r207325 - [Sema] Adjust Sema::getCurBlock()/getCurLambda() to take into account that we may have

Argyrios Kyrtzidis akyrtzi at gmail.com
Sat Apr 26 11:29:13 PDT 2014


Author: akirtzidis
Date: Sat Apr 26 13:29:13 2014
New Revision: 207325

URL: http://llvm.org/viewvc/llvm-project?rev=207325&view=rev
Log:
[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

Modified:
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaLambda.cpp
    cfe/trunk/test/SemaCXX/decltype.cpp

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=207325&r1=207324&r2=207325&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sat Apr 26 13:29:13 2014
@@ -1114,14 +1114,30 @@ BlockScopeInfo *Sema::getCurBlock() {
   if (FunctionScopes.empty())
     return 0;
 
-  return dyn_cast<BlockScopeInfo>(FunctionScopes.back());
+  auto CurBSI = dyn_cast<BlockScopeInfo>(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<LambdaScopeInfo>(FunctionScopes.back());
+  auto CurLSI = dyn_cast<LambdaScopeInfo>(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.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=207325&r1=207324&r2=207325&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Apr 26 13:29:13 2014
@@ -10557,7 +10557,7 @@ ExprResult Sema::ActOnBlockStmtExpr(Sour
   // 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();

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=207325&r1=207324&r2=207325&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Sat Apr 26 13:29:13 2014
@@ -1139,6 +1139,8 @@ void Sema::ActOnStartOfLambdaDefinition(
 
 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(SourceLocati
     PopDeclContext();
 
   // Finalize the lambda.
-  LambdaScopeInfo *LSI = getCurLambda();
   CXXRecordDecl *Class = LSI->Lambda;
   Class->setInvalidDecl();
   SmallVector<Decl*, 4> Fields(Class->fields());

Modified: cfe/trunk/test/SemaCXX/decltype.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decltype.cpp?rev=207325&r1=207324&r2=207325&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decltype.cpp (original)
+++ cfe/trunk/test/SemaCXX/decltype.cpp Sat Apr 26 13:29:13 2014
@@ -16,6 +16,27 @@ void test_f2() {
   float &fr = f2(AC().a);
 }
 
+template <class T>
+struct Future {
+  explicit Future(T v);
+
+  template <class F>
+  auto call(F&& fn) -> decltype(fn(T())) {
+    return fn(T());
+  }
+
+  template <class B, class F>
+  auto then(F&& fn) -> decltype(call(fn))
+  {
+    return fn(T());
+  }
+};
+
+void rdar16527205() {
+  Future<int> f1(42);
+  f1.call([](int){ return Future<float>(0); });
+}
+
 namespace pr10154 {
   class A{
       A(decltype(nullptr) param);





More information about the cfe-commits mailing list