Check that the access specifier of a member redeclaration is the same as the original declaration.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67722 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2009-03-26 00:24:17 +00:00
Родитель bbf462314b
Коммит 50713450f6
3 изменённых файлов: 47 добавлений и 3 удалений

Просмотреть файл

@ -234,6 +234,12 @@ def err_deleted_non_function : Error<
def err_deleted_decl_not_first : Error<
"deleted definition must be first declaration">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
"%0 redeclared with '%1' access">;
def note_previous_access_declaration : Note<
"previously declared '%1' here">;
// C++ name lookup
def err_incomplete_nested_name_spec : Error<
"incomplete type %0 named in nested name specifier">;

Просмотреть файл

@ -3083,6 +3083,21 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
return NewTD;
}
static const char *getAccessName(AccessSpecifier AS) {
switch (AS) {
default:
case AS_none:
assert("Invalid access specifier!");
return 0;
case AS_public:
return "public";
case AS_private:
return "private";
case AS_protected:
return "protected";
}
}
/// ActOnTag - This is invoked when we see 'struct foo' or 'struct {'. In the
/// former case, Name will be non-null. In the later case, Name will be null.
/// TagSpec indicates what kind of tag this is. TK indicates whether this is a
@ -3384,9 +3399,17 @@ CreateNewDecl:
// lexical context will be different from the semantic context.
New->setLexicalDeclContext(CurContext);
if (PrevDecl)
New->setAccess(PrevDecl->getAccess());
else
if (PrevDecl) {
// C++ [class.access.spec]p3: When a member is redeclared its access
// specifier must be same as its initial declaration.
if (AS != AS_none && AS != PrevDecl->getAccess()) {
Diag(Loc, diag::err_class_redeclared_with_different_access)
<< New << getAccessName(AS);
Diag(PrevDecl->getLocation(), diag::note_previous_access_declaration)
<< PrevDecl << getAccessName(PrevDecl->getAccess());
} else
New->setAccess(PrevDecl->getAccess());
} else
New->setAccess(AS);
if (TK == TK_Definition)

15
test/SemaCXX/access.cpp Normal file
Просмотреть файл

@ -0,0 +1,15 @@
// RUN: clang-cc -fsyntax-only -verify %s
class C {
struct S; // expected-note {{previously declared 'private' here}}
public:
struct S {}; // expected-error {{'S' redeclared with 'public' access}}
};
struct S {
class C; // expected-note {{previously declared 'public' here}}
private:
class C { }; // expected-error {{'C' redeclared with 'private' access}}
};