Handle delayed access in local declarations. PR9229.

llvm-svn: 125609
This commit is contained in:
John McCall 2011-02-15 22:51:53 +00:00
parent 24bbc46208
commit 9743e8d84e
2 changed files with 29 additions and 10 deletions

View 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());

View 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)]);
}
}