[cfe-commits] r67722 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaCXX/access.cpp
Anders Carlsson
andersca at mac.com
Wed Mar 25 17:24:25 PDT 2009
Author: andersca
Date: Wed Mar 25 19:24:17 2009
New Revision: 67722
URL: http://llvm.org/viewvc/llvm-project?rev=67722&view=rev
Log:
Check that the access specifier of a member redeclaration is the same as the original declaration.
Added:
cfe/trunk/test/SemaCXX/access.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=67722&r1=67721&r2=67722&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Mar 25 19:24:17 2009
@@ -234,6 +234,12 @@
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">;
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=67722&r1=67721&r2=67722&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Mar 25 19:24:17 2009
@@ -3083,6 +3083,21 @@
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 @@
// 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)
Added: cfe/trunk/test/SemaCXX/access.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/access.cpp?rev=67722&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/access.cpp (added)
+++ cfe/trunk/test/SemaCXX/access.cpp Wed Mar 25 19:24:17 2009
@@ -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}}
+};
\ No newline at end of file
More information about the cfe-commits
mailing list