diff options
author | Anders Carlsson <andersca@mac.com> | 2009-03-26 00:24:17 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-03-26 00:24:17 +0000 |
commit | 50713450f61b85805e1ca97e547a4082b7798bd3 (patch) | |
tree | 20856bc121adb7398bf1fb648fbe397a2be064b8 /lib/Sema/SemaDecl.cpp | |
parent | bbf462314b1dc8e422b7c4dd4cac47e566aedf6d (diff) |
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
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 88c08b0f75..d974301785 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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) |