r183722 - Implement DR85: Redeclaration of member is forbidden
David Majnemer
david.majnemer at gmail.com
Mon Jun 10 20:51:23 PDT 2013
Author: majnemer
Date: Mon Jun 10 22:51:23 2013
New Revision: 183722
URL: http://llvm.org/viewvc/llvm-project?rev=183722&view=rev
Log:
Implement DR85: Redeclaration of member is forbidden
Disallow the existence of a declaration of a member class that isn't a
forward declaration before it's definition.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/CXX/drs/dr0xx.cpp
cfe/trunk/test/SemaCXX/access.cpp
cfe/trunk/test/SemaTemplate/dependent-names.cpp
cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp
cfe/trunk/www/cxx_dr_status.html
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=183722&r1=183721&r2=183722&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jun 10 22:51:23 2013
@@ -4241,6 +4241,8 @@ def note_enum_specialized_here : Note<
"enum %0 was explicitly specialized here">;
def err_member_redeclared : Error<"class member cannot be redeclared">;
+def ext_member_redeclared : ExtWarn<"class member cannot be redeclared">,
+ InGroup<GNU>;
def err_member_redeclared_in_instantiation : Error<
"multiple overloads of %0 instantiate to the same signature %1">;
def err_member_name_of_class : Error<"member %0 has the same name as its class">;
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=183722&r1=183721&r2=183722&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jun 10 22:51:23 2013
@@ -9885,6 +9885,16 @@ Decl *Sema::ActOnTag(Scope *S, unsigned
return TUK == TUK_Declaration ? PrevTagDecl : 0;
}
+ // C++11 [class.mem]p1:
+ // A member shall not be declared twice in the member-speciï¬cation,
+ // except that a nested class or member class template can be declared
+ // and then later defined.
+ if (TUK == TUK_Declaration && PrevDecl->isCXXClassMember() &&
+ S->isDeclScope(PrevDecl)) {
+ Diag(NameLoc, diag::ext_member_redeclared);
+ Diag(PrevTagDecl->getLocation(), diag::note_previous_declaration);
+ }
+
if (!Invalid) {
// If this is a use, just return the declaration we found.
Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=183722&r1=183721&r2=183722&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr0xx.cpp Mon Jun 10 22:51:23 2013
@@ -862,15 +862,31 @@ namespace dr84 { // dr84: yes
B b = a; // expected-error {{no viable}}
}
-namespace dr85 { // dr85: no
+namespace dr85 { // dr85: yes
struct A {
struct B;
- struct B {};
- // FIXME: This redeclaration is invalid. Per [class.mem]p1,
- // "A member shall not be declared twice in the member-specification,
- // except that a nested class [...] can be declared then later defined"
- // This is not that case.
- struct B;
+ struct B {}; // expected-note{{previous declaration is here}}
+ struct B; // expected-error{{class member cannot be redeclared}}
+
+ union U;
+ union U {}; // expected-note{{previous declaration is here}}
+ union U; // expected-error{{class member cannot be redeclared}}
+
+#if __cplusplus >= 201103L
+ enum E1 : int;
+ enum E1 : int { e1 }; // expected-note{{previous declaration is here}}
+ enum E1 : int; // expected-error{{class member cannot be redeclared}}
+
+ enum class E2;
+ enum class E2 { e2 }; // expected-note{{previous declaration is here}}
+ enum class E2; // expected-error{{class member cannot be redeclared}}
+#endif
+ };
+
+ template <typename T>
+ struct C {
+ struct B {}; // expected-note{{previous declaration is here}}
+ struct B; // expected-error{{class member cannot be redeclared}}
};
}
Modified: cfe/trunk/test/SemaCXX/access.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/access.cpp?rev=183722&r1=183721&r2=183722&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/access.cpp (original)
+++ cfe/trunk/test/SemaCXX/access.cpp Mon Jun 10 22:51:23 2013
@@ -26,9 +26,11 @@ private:
namespace test1 {
class A {
private:
- class X; // expected-note {{previously declared 'private' here}}
+ class X; // expected-note {{previously declared 'private' here}} \
+ // expected-note {{previous declaration is here}}
public:
- class X; // expected-error {{'X' redeclared with 'public' access}}
+ class X; // expected-error {{'X' redeclared with 'public' access}} \
+ // expected-warning {{class member cannot be redeclared}}
class X {};
};
}
Modified: cfe/trunk/test/SemaTemplate/dependent-names.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-names.cpp?rev=183722&r1=183721&r2=183722&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-names.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-names.cpp Mon Jun 10 22:51:23 2013
@@ -354,7 +354,6 @@ namespace rdar12629723 {
struct A : public B { // expected-note{{'rdar12629723::X::A' declared here}}
virtual void foo() { }
};
- struct B;
struct D : T::foo { };
struct E : D { };
Modified: cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp?rev=183722&r1=183721&r2=183722&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp Mon Jun 10 22:51:23 2013
@@ -91,13 +91,11 @@ namespace test2 {
typedef int X;
};
typename Foo::X x;
- class Foo;
};
template class B<int>;
template <typename T> class C {
class Foo;
- class Foo;
};
template <typename T> class C<T>::Foo {
int x;
Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=183722&r1=183721&r2=183722&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Mon Jun 10 22:51:23 2013
@@ -548,7 +548,7 @@
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#85">85</a></td>
<td>TC1</td>
<td>Redeclaration of member class</td>
- <td class="none" align="center">No</td>
+ <td class="full" align="center">Yes</td>
</tr>
<tr>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#86">86</a></td>
More information about the cfe-commits
mailing list