From 00980eb82ffc9799f5c5cbf5f41f27c270e3c259 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 23 Mar 2016 20:07:07 +0000 Subject: [PATCH] Make sure to perform dependent access checks when instantiating a lambda-expression. We don't actually instantiate the closure type / operator() in the template in order to produce the closure type / operator() in the instantiation, so this isn't caught by the normal path. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@264184 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaLambda.cpp | 19 +++++++------------ lib/Sema/SemaTemplateInstantiate.cpp | 5 +++++ test/SemaCXX/access.cpp | 11 +++++++++++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 0f5eb41352..1dd37bd2d2 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -809,19 +809,14 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, bool KnownDependent = false; LambdaScopeInfo *const LSI = getCurLambda(); assert(LSI && "LambdaScopeInfo should be on stack!"); - TemplateParameterList *TemplateParams = - getGenericLambdaTemplateParameterList(LSI, *this); - - if (Scope *TmplScope = CurScope->getTemplateParamParent()) { - // Since we have our own TemplateParams, so check if an outer scope - // has template params, only then are we in a dependent scope. - if (TemplateParams) { - TmplScope = TmplScope->getParent(); - TmplScope = TmplScope ? TmplScope->getTemplateParamParent() : nullptr; - } - if (TmplScope && !TmplScope->decl_empty()) + + // The lambda-expression's closure type might be dependent even if its + // semantic context isn't, if it appears within a default argument of a + // function template. + if (Scope *TmplScope = CurScope->getTemplateParamParent()) + if (!TmplScope->decl_empty()) KnownDependent = true; - } + // Determine the signature of the call operator. TypeSourceInfo *MethodTyInfo; bool ExplicitParams = true; diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 610817fcaf..42344e487c 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -729,6 +729,11 @@ namespace { } SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New); + + // We recreated a local declaration, but not by instantiating it. There + // may be pending dependent diagnostics to produce. + if (auto *DC = dyn_cast(Old)) + SemaRef.PerformDependentDiagnostics(DC, TemplateArgs); } /// \brief Transform the definition of the given declaration by diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp index 5fa1509c53..cd65f907b8 100644 --- a/test/SemaCXX/access.cpp +++ b/test/SemaCXX/access.cpp @@ -158,3 +158,14 @@ namespace LocalExternVar { int array[sizeof(test::private_struct)]; // expected-error {{private}} } + +namespace ThisLambdaIsNotMyFriend { + class A { + friend class D; + static void foo(); // expected-note {{here}} + }; + template void foo() { + []() { A::foo(); }(); // expected-error {{private}} + } + void bar() { foo(); } // expected-note {{instantiation}} +} -- 2.40.0