aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-03-26 00:24:17 +0000
committerAnders Carlsson <andersca@mac.com>2009-03-26 00:24:17 +0000
commit50713450f61b85805e1ca97e547a4082b7798bd3 (patch)
tree20856bc121adb7398bf1fb648fbe397a2be064b8 /lib/Sema/SemaDecl.cpp
parentbbf462314b1dc8e422b7c4dd4cac47e566aedf6d (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.cpp29
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)