]> granicus.if.org Git - clang/commitdiff
Make sure to perform dependent access checks when instantiating a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 23 Mar 2016 20:07:07 +0000 (20:07 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 23 Mar 2016 20:07:07 +0000 (20:07 +0000)
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
lib/Sema/SemaTemplateInstantiate.cpp
test/SemaCXX/access.cpp

index 0f5eb4135267558b7719d5d8368022be8cac7668..1dd37bd2d26ac90f29febb4a88666f795f130b9e 100644 (file)
@@ -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;
index 610817fcafddc4a87f06224a1eb90d4bed4ae950..42344e487ce514f8fad619d95c24c06df43833fc 100644 (file)
@@ -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
index 5fa1509c530213227095f72963b3ba54701cff08..cd65f907b8b58a4c52792d39dd4ec8418af14334 100644 (file)
@@ -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}}
+}