From: Akira Hatanaka Date: Thu, 28 Apr 2016 23:50:12 +0000 (+0000) Subject: [Sema] Fix a crash that occurs when a variable template is initialized X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4eaa6552bba77670e89d3bf6fab1e30f669141b6;p=clang [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 --- 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(); +}