erik.pilkington created this revision.
erik.pilkington added reviewers: faisalv, rsmith, ahatanak.
erik.pilkington added a subscriber: cfe-commits.

Clang crashes during the instantiation of a lambda call operator where a 
`VarDecl` is initialized with an expression that requires the `this` type of 
the enclosing class, because when instantiating the initializing expression we 
introduce a new context which nulls out the `Sema::CXXThisTypeOverride`. This 
patch fixes the crash by retaining the 'this' type when the current lexical 
context is the body of the lambda.

This is a regression from 3.8 introduced in r267956. Fixes PR27994.

Thanks!

http://reviews.llvm.org/D21145

Files:
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaCXX/lambda-expressions.cpp

Index: test/SemaCXX/lambda-expressions.cpp
===================================================================
--- test/SemaCXX/lambda-expressions.cpp
+++ test/SemaCXX/lambda-expressions.cpp
@@ -499,3 +499,15 @@
   };
 }
 }
+
+namespace PR27994 {
+struct A { template <class T> A(T); };
+
+template <class T>
+struct B {
+  int x;
+  A a = [&] { int y = x; };
+};
+
+B<int> b;
+}
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -12,6 +12,7 @@
 #include "clang/Sema/SemaInternal.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
@@ -3916,7 +3917,9 @@
     ExprResult Init;
 
     {
-      ContextRAII SwitchContext(*this, Var->getDeclContext());
+      ContextRAII SwitchContext(
+          *this, Var->getDeclContext(),
+          /*NewThisContext=*/!isLambdaCallOperator(getCurLexicalContext()));
       Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
                               OldVar->getInitStyle() == VarDecl::CallInit);
     }


Index: test/SemaCXX/lambda-expressions.cpp
===================================================================
--- test/SemaCXX/lambda-expressions.cpp
+++ test/SemaCXX/lambda-expressions.cpp
@@ -499,3 +499,15 @@
   };
 }
 }
+
+namespace PR27994 {
+struct A { template <class T> A(T); };
+
+template <class T>
+struct B {
+  int x;
+  A a = [&] { int y = x; };
+};
+
+B<int> b;
+}
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -12,6 +12,7 @@
 #include "clang/Sema/SemaInternal.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
@@ -3916,7 +3917,9 @@
     ExprResult Init;
 
     {
-      ContextRAII SwitchContext(*this, Var->getDeclContext());
+      ContextRAII SwitchContext(
+          *this, Var->getDeclContext(),
+          /*NewThisContext=*/!isLambdaCallOperator(getCurLexicalContext()));
       Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
                               OldVar->getInitStyle() == VarDecl::CallInit);
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to