r264184 - Make sure to perform dependent access checks when instantiating a

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 23 13:07:07 PDT 2016


Author: rsmith
Date: Wed Mar 23 15:07:07 2016
New Revision: 264184

URL: http://llvm.org/viewvc/llvm-project?rev=264184&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/Sema/SemaLambda.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaCXX/access.cpp

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=264184&r1=264183&r2=264184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Wed Mar 23 15:07:07 2016
@@ -809,19 +809,14 @@ void Sema::ActOnStartOfLambdaDefinition(
   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;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=264184&r1=264183&r2=264184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Mar 23 15:07:07 2016
@@ -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

Modified: cfe/trunk/test/SemaCXX/access.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/access.cpp?rev=264184&r1=264183&r2=264184&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/access.cpp (original)
+++ cfe/trunk/test/SemaCXX/access.cpp Wed Mar 23 15:07:07 2016
@@ -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}}
+}




More information about the cfe-commits mailing list