diff options
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 9 | ||||
-rw-r--r-- | clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp | 33 |
3 files changed, 40 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6b66a42ad34..5202f96354d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3128,6 +3128,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, // the semantic constraints are checked, at the point where the // default argument expression appears. ContextRAII SavedContext(*this, FD); + LocalInstantiationScope Local(*this); Result = SubstExpr(UninstExpr, ArgList); } if (Result.isInvalid()) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index f4808254123..d491dfc51ed 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2629,7 +2629,8 @@ void Sema::InstantiateStaticDataMemberDefinition( // Enter the scope of this instantiation. We don't use // PushDeclContext because we don't have a scope. ContextRAII previousContext(*this, Var->getDeclContext()); - + LocalInstantiationScope Local(*this); + VarDecl *OldVar = Var; Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(), getTemplateInstantiationArgs(Var))); @@ -2644,7 +2645,8 @@ void Sema::InstantiateStaticDataMemberDefinition( DeclGroupRef DG(Var); Consumer.HandleTopLevelDecl(DG); } - + Local.Exit(); + if (Recursive) { // Define any newly required vtables. DefineUsedVTables(); @@ -3096,7 +3098,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, DeclContext *ParentDC = D->getDeclContext(); if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) || - (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) { + (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext()) || + (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) { // D is a local of some kind. Look into the map of local // declarations to their instantiations. typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp index 14491cc3b20..49b9c66b1ce 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp @@ -114,3 +114,36 @@ namespace p5 { template void double_capture(NonConstCopy&); } + +namespace NonLocalLambdaInstantation { + template<typename T> + struct X { + static int value; + }; + + template<typename T> + int X<T>::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}} + + template int X<int>::value; + template int X<float>::value; + template int X<int*>::value; // expected-note{{in instantiation of static data member }} + + template<typename T> + void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \ + // expected-note{{passing argument to parameter 'x' here}} + + void call_defaults() { + defaults<int>(); + defaults<float>(); + defaults<int*>(); // expected-note{{in instantiation of default function argument expression for 'defaults<int *>' required here}} + } + + template<typename T> + struct X2 { + int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}} + }; + + X2<int> x2i; + X2<float> x2f; + X2<int*> x2ip; // expected-note{{in instantiation of template class 'NonLocalLambdaInstantation::X2<int *>' requested here}} +} |