From 4eaa6552bba77670e89d3bf6fab1e30f669141b6 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 28 Apr 2016 23:50:12 +0000 Subject: [PATCH] [Sema] Fix a crash that occurs when a variable template is initialized 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 | 11 ++++++++--- test/SemaCXX/vartemplate-lambda.cpp | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 test/SemaCXX/vartemplate-lambda.cpp diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8e42be0ee2..66b274f626 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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 index 0000000000..d5ad155d0e --- /dev/null +++ b/test/SemaCXX/vartemplate-lambda.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// expected-no-diagnostics + +template auto fn1 = [](auto a) { return a + T(1); }; + +template +int foo2() { + X a = 0x61; + fn1(a); + return 0; +} + +int main() { + foo2(); +} -- 2.40.0