forked from OSchip/llvm-project
Access control polish: drop the note on the original declaration and
say 'implicitly' when it was implicit. Resolves PR 7930 and my peace of mind. llvm-svn: 116916
This commit is contained in:
parent
af719ef86b
commit
f551acaaf5
|
@ -1008,9 +1008,51 @@ static void DiagnoseAccessPath(Sema &S,
|
|||
TryDiagnoseProtectedAccess(S, EC, Entity))
|
||||
return;
|
||||
|
||||
// Find an original declaration.
|
||||
while (D->isOutOfLine()) {
|
||||
NamedDecl *PrevDecl = 0;
|
||||
if (isa<VarDecl>(D))
|
||||
PrevDecl = cast<VarDecl>(D)->getPreviousDeclaration();
|
||||
else if (isa<FunctionDecl>(D))
|
||||
PrevDecl = cast<FunctionDecl>(D)->getPreviousDeclaration();
|
||||
else if (isa<TypedefDecl>(D))
|
||||
PrevDecl = cast<TypedefDecl>(D)->getPreviousDeclaration();
|
||||
else if (isa<TagDecl>(D)) {
|
||||
if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
|
||||
break;
|
||||
PrevDecl = cast<TagDecl>(D)->getPreviousDeclaration();
|
||||
}
|
||||
if (!PrevDecl) break;
|
||||
D = PrevDecl;
|
||||
}
|
||||
|
||||
CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
|
||||
Decl *ImmediateChild;
|
||||
if (D->getDeclContext() == DeclaringClass)
|
||||
ImmediateChild = D;
|
||||
else {
|
||||
DeclContext *DC = D->getDeclContext();
|
||||
while (DC->getParent() != DeclaringClass)
|
||||
DC = DC->getParent();
|
||||
ImmediateChild = cast<Decl>(DC);
|
||||
}
|
||||
|
||||
// Check whether there's an AccessSpecDecl preceding this in the
|
||||
// chain of the DeclContext.
|
||||
bool Implicit = true;
|
||||
for (CXXRecordDecl::decl_iterator
|
||||
I = DeclaringClass->decls_begin(), E = DeclaringClass->decls_end();
|
||||
I != E; ++I) {
|
||||
if (*I == ImmediateChild) break;
|
||||
if (isa<AccessSpecDecl>(*I)) {
|
||||
Implicit = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
S.Diag(D->getLocation(), diag::note_access_natural)
|
||||
<< (unsigned) (Access == AS_protected)
|
||||
<< /*FIXME: not implicitly*/ 0;
|
||||
<< Implicit;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -258,13 +258,12 @@ namespace test7 {
|
|||
namespace test8 {
|
||||
class A {
|
||||
typedef int I; // expected-note 4 {{declared private here}}
|
||||
static const I x = 0;
|
||||
static const I x = 0; // expected-note {{implicitly declared private here}}
|
||||
friend I f(I i);
|
||||
template<typename T> friend I g(I i);
|
||||
};
|
||||
|
||||
// FIXME: This should be on line 264.
|
||||
const A::I A::x; // expected-note {{declared private here}}
|
||||
const A::I A::x;
|
||||
A::I f(A::I i = A::x) {}
|
||||
template<typename T> A::I g(A::I i) {
|
||||
T t;
|
||||
|
|
|
@ -201,7 +201,7 @@ namespace test4 {
|
|||
// Implicit copy assignment operator uses.
|
||||
namespace test5 {
|
||||
class A {
|
||||
void operator=(const A &); // expected-note 2 {{declared private here}}
|
||||
void operator=(const A &); // expected-note 2 {{implicitly declared private here}}
|
||||
};
|
||||
|
||||
class Test1 { A a; }; // expected-error {{private member}}
|
||||
|
@ -458,3 +458,33 @@ namespace test19 {
|
|||
// testing PR7281, earlier in this file.
|
||||
void b(A* x) { throw x; }
|
||||
}
|
||||
|
||||
// PR7930
|
||||
namespace test20 {
|
||||
class Foo {
|
||||
Foo(); // expected-note {{implicitly declared private here}}
|
||||
};
|
||||
Foo::Foo() {}
|
||||
|
||||
void test() {
|
||||
Foo a; // expected-error {{calling a private constructor}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace test21 {
|
||||
template <class T> class A {
|
||||
void foo();
|
||||
void bar();
|
||||
class Inner; // expected-note {{implicitly declared private here}}
|
||||
public:
|
||||
void baz();
|
||||
};
|
||||
template <class T> class A<T>::Inner {};
|
||||
class B {
|
||||
template <class T> class A<T>::Inner;
|
||||
};
|
||||
|
||||
void test() {
|
||||
A<int>::Inner i; // expected-error {{'Inner' is a private member}}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue