summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-03-23 20:07:07 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-03-23 20:07:07 +0000
commitc7649dc74995be4239b7b4ac05d36959e2d7d4ad (patch)
treebef903ff99caf99534b60c94ea5714a2a0753c88
parent613112826e1088a90b3e95597b0f7049d35bcb4b (diff)
downloadbcm5719-llvm-c7649dc74995be4239b7b4ac05d36959e2d7d4ad.tar.gz
bcm5719-llvm-c7649dc74995be4239b7b4ac05d36959e2d7d4ad.zip
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. llvm-svn: 264184
-rw-r--r--clang/lib/Sema/SemaLambda.cpp19
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp5
-rw-r--r--clang/test/SemaCXX/access.cpp11
3 files changed, 23 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 0f5eb413526..1dd37bd2d26 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 610817fcafd..42344e487ce 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/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<DeclContext>(Old))
+ SemaRef.PerformDependentDiagnostics(DC, TemplateArgs);
}
/// \brief Transform the definition of the given declaration by
diff --git a/clang/test/SemaCXX/access.cpp b/clang/test/SemaCXX/access.cpp
index 5fa1509c530..cd65f907b8b 100644
--- a/clang/test/SemaCXX/access.cpp
+++ b/clang/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 <class T> void foo() {
+ []() { A::foo(); }(); // expected-error {{private}}
+ }
+ void bar() { foo<void>(); } // expected-note {{instantiation}}
+}
OpenPOWER on IntegriCloud