From: Chandler Carruth Date: Sun, 18 Apr 2010 08:23:21 +0000 (+0000) Subject: Fix the access checking of function and function template argument types, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=630eb01b2568d0958118eb1a0ded02bebecb2b0f;p=clang Fix the access checking of function and function template argument types, return types, and default arguments. This fixes PR6855 along with several similar cases where we rejected valid code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101706 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 520a9708c6..352477b859 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -1015,8 +1015,15 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx) { // Pretend we did this from the context of the newly-parsed - // declaration. - EffectiveContext EC(Ctx->getDeclContext()); + // 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(Ctx)) + DC = cast(Ctx); + else if (FunctionTemplateDecl *FnTpl = dyn_cast(Ctx)) + DC = cast(FnTpl->getTemplatedDecl()); + EffectiveContext EC(DC); AccessTarget Target(DD.getAccessData()); diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index 8dffd1dd86..91d7661be3 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -256,3 +256,27 @@ namespace test7 { A a; // expected-error {{calling a private constructor}} } } + +// Return types, parameters and default arguments to friend functions. +namespace test8 { + class A { + typedef int I; // expected-note 4 {{declared private here}} + static const I x = 0; + friend I f(I i); + template friend I g(I i); + }; + + // FIXME: This should be on line 264. + const A::I A::x; // expected-note {{declared private here}} + A::I f(A::I i = A::x) {} + template A::I g(A::I i) { + T t; + } + template A::I g(A::I i); + + A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}} + template A::I g2(A::I i) { // expected-error 2 {{is a private member of}} + T t; + } + template A::I g2(A::I i); +}