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 | 2ed6ceba1d905ab4d7d9695b7de1b472d3035f49 (patch) | |
tree | 8ff0e4661e977335123c915c0faf7503d2b7a198 /clang/lib/Sema/SemaDecl.cpp | |
parent | 8d7ff4098ccff8ce137ce487c24eb55ffc445dfb (diff) | |
download | bcm5719-llvm-2ed6ceba1d905ab4d7d9695b7de1b472d3035f49.tar.gz bcm5719-llvm-2ed6ceba1d905ab4d7d9695b7de1b472d3035f49.zip |
Check that the access specifier of a member redeclaration is the same as the original declaration.
llvm-svn: 67722
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 88c08b0f751..d9743017850 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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) |