]> granicus.if.org Git - clang/commitdiff
Handle delayed access in local declarations. PR9229.
authorJohn McCall <rjmccall@apple.com>
Tue, 15 Feb 2011 22:51:53 +0000 (22:51 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 15 Feb 2011 22:51:53 +0000 (22:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125609 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaAccess.cpp
test/CXX/class.access/p6.cpp

index 3103255d200172bb6c03408ea7e58d3b6ada9006..4f9bf1c5edd76751fe355b561904bcfc067697e0 100644 (file)
@@ -1286,16 +1286,20 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
   return Sema::AR_accessible;
 }
 
-void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx) {
-  // Pretend we did this from the context of the newly-parsed
-  // declaration. If that declaration itself forms a declaration context,
-  // include it in the effective context so that parameters and return types of
-  // befriended functions have that function's access priveledges.
-  DeclContext *DC = Ctx->getDeclContext();
-  if (isa<FunctionDecl>(Ctx))
-    DC = cast<DeclContext>(Ctx);
-  else if (FunctionTemplateDecl *FnTpl = dyn_cast<FunctionTemplateDecl>(Ctx))
-    DC = cast<DeclContext>(FnTpl->getTemplatedDecl());
+void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) {
+  // Access control for names used in the declarations of functions
+  // and function templates should normally be evaluated in the context
+  // of the declaration, just in case it's a friend of something.
+  // However, this does not apply to local extern declarations.
+
+  DeclContext *DC = decl->getDeclContext();
+  if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
+    if (!DC->isFunctionOrMethod()) DC = fn;
+  } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
+    // Never a local declaration.
+    DC = fnt->getTemplatedDecl();
+  }
+
   EffectiveContext EC(DC);
 
   AccessTarget Target(DD.getAccessData());
index 1112699c8b9ad05f4ba380edb3d22f53e5e299f2..fe3304a22253df6479a73c8aab611dde0f7ec5da 100644 (file)
@@ -153,3 +153,18 @@ namespace test6 {
     private_inner c; // expected-error {{ 'private_inner' is a private member of 'test6::A'}}
   };
 }
+
+// PR9229
+namespace test7 {
+  void foo(int arg[1]);
+  class A {
+    void check();
+  };
+  class B {
+    friend class A;
+    A ins;
+  };
+  void A::check() {
+    void foo(int arg[__builtin_offsetof(B, ins)]);
+  }
+}