]> granicus.if.org Git - clang/commitdiff
[Sema] Fix a crash that occurs when a variable template is initialized
authorAkira Hatanaka <ahatanaka@apple.com>
Thu, 28 Apr 2016 23:50:12 +0000 (23:50 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Thu, 28 Apr 2016 23:50:12 +0000 (23:50 +0000)
with a generic lambda.

This patch fixes Sema::InstantiateVariableInitializer to switch to the
context of the variable before instantiating its initializer, which is
necessary to set the correct type for VarTemplateSpecializationDecl.

This is the first part of the patch that was reviewed here:
http://reviews.llvm.org/D19175

rdar://problem/23440346

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@267956 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaCXX/vartemplate-lambda.cpp [new file with mode: 0644]

index 8e42be0ee2e7186d687e5a6e0132ae8083f4af63..66b274f62604264dc0761e257954aa448363d0f4 100644 (file)
@@ -3907,9 +3907,14 @@ void Sema::InstantiateVariableInitializer(
       PushExpressionEvaluationContext(Sema::PotentiallyEvaluated, OldVar);
 
     // Instantiate the initializer.
-    ExprResult Init =
-        SubstInitializer(OldVar->getInit(), TemplateArgs,
-                         OldVar->getInitStyle() == VarDecl::CallInit);
+    ExprResult Init;
+
+    {
+      ContextRAII SwitchContext(*this, Var->getDeclContext());
+      Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
+                              OldVar->getInitStyle() == VarDecl::CallInit);
+    }
+
     if (!Init.isInvalid()) {
       bool TypeMayContainAuto = true;
       Expr *InitExpr = Init.get();
diff --git a/test/SemaCXX/vartemplate-lambda.cpp b/test/SemaCXX/vartemplate-lambda.cpp
new file mode 100644 (file)
index 0000000..d5ad155
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+template<typename T> auto fn1 = [](auto a) { return a + T(1); };
+
+template <typename X>
+int foo2() {
+  X a = 0x61;
+  fn1<char>(a);
+  return 0;
+}
+
+int main() {
+  foo2<int>();
+}