Author: rsmith Date: Sun Jul 5 20:45:27 2015 New Revision: 241425 URL: http://llvm.org/viewvc/llvm-project?rev=241425&view=rev Log: DR1909: Diagnose all invalid cases of a class member sharing its name with the class.
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/CXX/class/class.mem/p13.cpp cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp cfe/trunk/test/CXX/drs/dr19xx.cpp cfe/trunk/test/CXX/drs/dr3xx.cpp cfe/trunk/test/SemaCXX/alias-template.cpp cfe/trunk/test/SemaCXX/struct-class-redecl.cpp cfe/trunk/test/SemaTemplate/injected-class-name.cpp cfe/trunk/www/cxx_dr_status.html Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sun Jul 5 20:45:27 2015 @@ -543,10 +543,11 @@ Decl *Parser::ParseUsingDeclaration(unsi SourceLocation IdLoc = ConsumeToken(); ParsedType Type = Actions.getInheritingConstructorName(SS, IdLoc, *LastII); Name.setConstructorName(Type, IdLoc, IdLoc); - } else if (ParseUnqualifiedId(SS, /*EnteringContext=*/ false, - /*AllowDestructorName=*/ true, - /*AllowConstructorName=*/ true, ParsedType(), - TemplateKWLoc, Name)) { + } else if (ParseUnqualifiedId( + SS, /*EnteringContext=*/false, + /*AllowDestructorName=*/true, + /*AllowConstructorName=*/NextToken().isNot(tok::equal), + ParsedType(), TemplateKWLoc, Name)) { SkipUntil(tok::semi); return nullptr; } Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Jul 5 20:45:27 2015 @@ -11560,6 +11560,14 @@ Decl *Sema::ActOnTag(Scope *S, unsigned goto CreateNewDecl; } } else if (Name) { + // C++14 [class.mem]p14: + // If T is the name of a class, then each of the following shall have a + // name different from T: + // -- every member of class T that is itself a type + if (TUK != TUK_Reference && TUK != TUK_Friend && + DiagnoseClassNameShadow(SearchDC, DeclarationNameInfo(Name, NameLoc))) + return nullptr; + // If this is a named struct, check to see if there was a previous forward // declaration or definition. // FIXME: We're looking into outer scopes here, even when we @@ -13620,12 +13628,9 @@ Decl *Sema::ActOnEnumConstant(Scope *S, // different from T: // - every enumerator of every member of class T that is an unscoped // enumerated type - if (CXXRecordDecl *Record - = dyn_cast<CXXRecordDecl>( - TheEnumDecl->getDeclContext()->getRedeclContext())) - if (!TheEnumDecl->isScoped() && - Record->getIdentifier() && Record->getIdentifier() == Id) - Diag(IdLoc, diag::err_member_name_of_class) << Id; + if (!TheEnumDecl->isScoped()) + DiagnoseClassNameShadow(TheEnumDecl->getDeclContext(), + DeclarationNameInfo(Id, IdLoc)); EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst, IdLoc, Id, Val); Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sun Jul 5 20:45:27 2015 @@ -893,6 +893,16 @@ Sema::CheckClassTemplate(Scope *S, unsig LookupQualifiedName(Previous, SemanticContext); } else { SemanticContext = CurContext; + + // C++14 [class.mem]p14: + // If T is the name of a class, then each of the following shall have a + // name different from T: + // -- every member template of class T + if (TUK != TUK_Friend && + DiagnoseClassNameShadow(SemanticContext, + DeclarationNameInfo(Name, NameLoc))) + return true; + LookupName(Previous, S); } Modified: cfe/trunk/test/CXX/class/class.mem/p13.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mem/p13.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/test/CXX/class/class.mem/p13.cpp (original) +++ cfe/trunk/test/CXX/class/class.mem/p13.cpp Sun Jul 5 20:45:27 2015 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s // If T is the name of a class, then each of the following shall have // a name different from T: @@ -9,23 +9,53 @@ struct X0 { }; // - every member function of class T -// (Cannot be tested) +struct Xa { + int Xa() {} // expected-error{{constructor cannot have a return type}} +}; // - every member of class T that is itself a type; -struct X1 { // expected-note{{previous use is here}} - enum X1 { }; // expected-error{{use of 'X1' with tag type that does not match previous declaration}} +struct X1 { + enum X1 { }; // expected-error{{member 'X1' has the same name as its class}} +}; + +struct X1a { + struct X1a; // expected-error{{member 'X1a' has the same name as its class}} }; struct X2 { typedef int X2; // expected-error{{member 'X2' has the same name as its class}} }; -// - every enumerator of every member of class T that is an enumerated type; and +struct X2a { + using X2a = int; // expected-error{{member 'X2a' has the same name as its class}} +}; + +// - every member template of class T + +struct X2b { + template<typename T> struct X2b; // expected-error{{member 'X2b' has the same name as its class}} +}; +struct X2c { + template<typename T> void X2c(); // expected-error{{constructor cannot have a return type}} +}; +struct X2d { + template<typename T> static int X2d; // expected-error{{member 'X2d' has the same name as its class}} +}; +struct X2e { + template<typename T> using X2e = int; // expected-error{{member 'X2e' has the same name as its class}} +}; + +// - every enumerator of every member of class T that is an unscoped enumerated type; and struct X3 { enum E { X3 // expected-error{{member 'X3' has the same name as its class}} }; }; +struct X3a { + enum class E { + X3a // ok + }; +}; // - every member of every anonymous union that is a member of class T. struct X4 { @@ -37,4 +67,3 @@ struct X4 { }; }; }; - Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp (original) +++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp Sun Jul 5 20:45:27 2015 @@ -83,12 +83,10 @@ namespace InFunctions { namespace ClassNameRedecl { class C0 { - // FIXME: this diagnostic is pretty poor - using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}} + using C0 = int; // expected-error {{member 'C0' has the same name as its class}} }; class C1 { - // FIXME: this diagnostic is pretty poor - using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}} + using C1 = C1; // expected-error {{member 'C1' has the same name as its class}} }; class C2 { using C0 = C1; // ok Modified: cfe/trunk/test/CXX/drs/dr19xx.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr19xx.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/test/CXX/drs/dr19xx.cpp (original) +++ cfe/trunk/test/CXX/drs/dr19xx.cpp Sun Jul 5 20:45:27 2015 @@ -39,6 +39,21 @@ namespace dr1902 { // dr1902: 3.7 #endif } +namespace dr1909 { // dr1909: yes + struct A { + template<typename T> struct A {}; // expected-error {{member 'A' has the same name as its class}} + }; + struct B { + template<typename T> void B() {} // expected-error {{constructor cannot have a return type}} + }; + struct C { + template<typename T> static int C; // expected-error {{member 'C' has the same name as its class}} expected-error 0-1{{extension}} + }; + struct D { + template<typename T> using D = int; // expected-error {{member 'D' has the same name as its class}} expected-error 0-1{{extension}} + }; +} + #if __cplusplus >= 201103L namespace dr1940 { // dr1940: yes static union { Modified: cfe/trunk/test/CXX/drs/dr3xx.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/test/CXX/drs/dr3xx.cpp (original) +++ cfe/trunk/test/CXX/drs/dr3xx.cpp Sun Jul 5 20:45:27 2015 @@ -110,18 +110,6 @@ namespace dr305 { // dr305: no x->~X<char>(); // expected-error {{no member named}} } - // FIXME: This appears to be valid (but allowing the nested types might be a - // defect). - template<typename> struct Nested { - template<typename> struct Nested {}; - }; - void testNested(Nested<int> n) { n.~Nested<int>(); } // expected-error {{no member named}} -#if __cplusplus < 201103L - // expected-error@-2 {{ambiguous}} - // expected-note@-6 {{here}} - // expected-note@-6 {{here}} -#endif - #if __cplusplus >= 201103L struct Y { template<typename T> using T1 = Y; Modified: cfe/trunk/test/SemaCXX/alias-template.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/alias-template.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/alias-template.cpp (original) +++ cfe/trunk/test/SemaCXX/alias-template.cpp Sun Jul 5 20:45:27 2015 @@ -68,12 +68,10 @@ namespace InFunctions { namespace ClassNameRedecl { class C0 { - // FIXME: this diagnostic is pretty poor - template<typename U> using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}} + template<typename U> using C0 = int; // expected-error {{member 'C0' has the same name as its class}} }; class C1 { - // FIXME: this diagnostic is pretty poor - template<typename U> using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}} + template<typename U> using C1 = C1; // expected-error {{member 'C1' has the same name as its class}} }; class C2 { template<typename U> using C0 = C1; // ok Modified: cfe/trunk/test/SemaCXX/struct-class-redecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/struct-class-redecl.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/struct-class-redecl.cpp (original) +++ cfe/trunk/test/SemaCXX/struct-class-redecl.cpp Sun Jul 5 20:45:27 2015 @@ -8,8 +8,8 @@ template<typename T> struct Y; // expect template<class U> class Y { }; // expected-warning{{previously declared}} template <typename> -struct Z { // expected-note{{previous definition is here}} - struct Z { // expected-error{{nested redefinition of 'Z'}} +struct Z { + struct Z { // expected-error{{member 'Z' has the same name as its class}} }; }; Modified: cfe/trunk/test/SemaTemplate/injected-class-name.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/injected-class-name.cpp?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/injected-class-name.cpp (original) +++ cfe/trunk/test/SemaTemplate/injected-class-name.cpp Sun Jul 5 20:45:27 2015 @@ -60,3 +60,9 @@ namespace ForwardDecls { typename xt::foo *t; }; } + +namespace ConflictingRedecl { + template<typename> struct Nested { + template<typename> struct Nested; // expected-error {{member 'Nested' has the same name as its class}} + }; +} Modified: cfe/trunk/www/cxx_dr_status.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=241425&r1=241424&r2=241425&view=diff ============================================================================== --- cfe/trunk/www/cxx_dr_status.html (original) +++ cfe/trunk/www/cxx_dr_status.html Sun Jul 5 20:45:27 2015 @@ -5503,7 +5503,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#948">948</a></td> <td>C++11</td> <td><TT>constexpr</TT> in <I>condition</I>s</td> - <td class="none" align="center">Unknown</td> + <td class="svn" align="center">SVN</td> </tr> <tr class="open" id="949"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#949">949</a></td> @@ -11269,7 +11269,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1909">1909</a></td> <td>DR</td> <td>Member class template with the same name as the class</td> - <td class="none" align="center">Unknown</td> + <td class="full" align="center">Yes</td> </tr> <tr class="open" id="1910"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1910">1910</a></td> _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits