Index: lib/Sema/SemaAccess.cpp =================================================================== --- lib/Sema/SemaAccess.cpp +++ lib/Sema/SemaAccess.cpp @@ -84,10 +84,10 @@ : Inner(DC), Dependent(DC->isDependentContext()) { - // C++ [class.access.nest]p1: + // C++11 [class.access.nest]p1: // A nested class is a member and as such has the same access // rights as any other member. - // C++ [class.access]p2: + // C++11 [class.access]p2: // A member of a class can also access all the names to which // the class has access. A local class of a member function // may access the same names that the member function itself @@ -1476,18 +1476,18 @@ llvm_unreachable("falling off end"); } -void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) { +void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) { // 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(decl)) { - if (!DC->isFunctionOrMethod()) DC = fn; - } else if (FunctionTemplateDecl *fnt = dyn_cast(decl)) { - // Never a local declaration. - DC = fnt->getTemplatedDecl(); + DeclContext *DC = D->getDeclContext(); + if (FunctionDecl *FN = dyn_cast(D)) { + if (!DC->isFunctionOrMethod()) + DC = FN; + } else if (TemplateDecl *TD = dyn_cast(D)) { + DC = dyn_cast(TD->getTemplatedDecl()); } EffectiveContext EC(DC); Index: test/SemaCXX/access.cpp =================================================================== --- test/SemaCXX/access.cpp +++ test/SemaCXX/access.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s class C { struct S; // expected-note {{previously declared 'private' here}} @@ -32,3 +32,27 @@ class X {}; }; } + +// PR15209 +namespace PR15209 { + class A { + typedef int I; // expected-note {{implicitly declared private here}} + template friend struct B; + template struct C; + template friend struct E; + template class T> friend struct TT; + static constexpr int x = 0; + }; + template struct B { }; + + template struct A::C { }; + + template struct D { }; // expected-error {{'I' is a private member of 'PR15209::A'}} + + template struct E { }; + + template class T> struct TT { + T t; + }; + template struct TT; +}