On Thu, May 5, 2016 at 10:40 AM, Reid Kleckner <r...@google.com> wrote:
> FYI, this change broke bionic, which has this exact pattern: > > https://android.googlesource.com/platform/bionic/+/master/tools/relocation_packer/src/debug.h#84 > > struct A { > enum E { > X = 3 > }; > }; > typedef A::E T; > using T::X; > > I expect users are going to have lots of issues with this, and it probably > warrants a release note. > Given that GCC rejects this code (and has done for as long as it's accepted the Enum::Member syntax), I don't expect the problems to be too widespread. If they are, we could trivially accept this as an extension; it seems like a pointless restriction. > On Wed, May 4, 2016 at 7:13 PM, Richard Smith via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: rsmith >> Date: Wed May 4 21:13:49 2016 >> New Revision: 268594 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=268594&view=rev >> Log: >> Fix implementation of C++'s restrictions on using-declarations referring >> to enumerators: >> >> * an unscoped enumerator whose enumeration is a class member is itself a >> class >> member, so can only be the subject of a class-scope using-declaration. >> >> * a scoped enumerator cannot be the subject of a class-scope >> using-declaration. >> >> Added: >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp >> - copied, changed from r268583, >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp >> >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp >> - copied, changed from r268583, >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp >> Removed: >> >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp >> >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp >> Modified: >> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> cfe/trunk/lib/Sema/SemaDeclCXX.cpp >> cfe/trunk/test/CXX/drs/dr4xx.cpp >> cfe/trunk/test/SemaCXX/enum-scoped.cpp >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=268594&r1=268593&r2=268594&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed May 4 >> 21:13:49 2016 >> @@ -396,7 +396,9 @@ def note_using_decl_class_member_workaro >> "use %select{an alias declaration|a typedef declaration|a reference}0 " >> "instead">; >> def err_using_decl_can_not_refer_to_namespace : Error< >> - "using declaration cannot refer to namespace">; >> + "using declaration cannot refer to a namespace">; >> +def err_using_decl_can_not_refer_to_scoped_enum : Error< >> + "using declaration cannot refer to a scoped enumerator">; >> def err_using_decl_constructor : Error< >> "using declaration cannot refer to a constructor">; >> def warn_cxx98_compat_using_decl_constructor : Warning< >> >> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=268594&r1=268593&r2=268594&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed May 4 21:13:49 2016 >> @@ -7738,7 +7738,7 @@ bool Sema::CheckUsingShadowDecl(UsingDec >> // function will silently decide not to build a shadow decl, which >> // will pre-empt further diagnostics. >> // >> - // We don't need to do this in C++0x because we do the check once on >> + // We don't need to do this in C++11 because we do the check once on >> // the qualifier. >> // >> // FIXME: diagnose the following if we care enough: >> @@ -8227,7 +8227,7 @@ NamedDecl *Sema::BuildUsingDeclaration(S >> } >> } >> >> - // C++0x N2914 [namespace.udecl]p6: >> + // C++14 [namespace.udecl]p6: >> // A using-declaration shall not name a namespace. >> if (R.getAsSingle<NamespaceDecl>()) { >> Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace) >> @@ -8235,6 +8235,16 @@ NamedDecl *Sema::BuildUsingDeclaration(S >> return BuildInvalid(); >> } >> >> + // C++14 [namespace.udecl]p7: >> + // A using-declaration shall not name a scoped enumerator. >> + if (auto *ED = R.getAsSingle<EnumConstantDecl>()) { >> + if (cast<EnumDecl>(ED->getDeclContext())->isScoped()) { >> + Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_scoped_enum) >> + << SS.getRange(); >> + return BuildInvalid(); >> + } >> + } >> + >> UsingDecl *UD = BuildValid(); >> >> // The normal rules do not apply to inheriting constructor >> declarations. >> @@ -8359,8 +8369,10 @@ bool Sema::CheckUsingDeclQualifier(Sourc >> >> // If we weren't able to compute a valid scope, it must be a >> // dependent class scope. >> - if (!NamedContext || NamedContext->isRecord()) { >> - auto *RD = dyn_cast_or_null<CXXRecordDecl>(NamedContext); >> + if (!NamedContext || NamedContext->getRedeclContext()->isRecord()) { >> + auto *RD = NamedContext >> + ? >> cast<CXXRecordDecl>(NamedContext->getRedeclContext()) >> + : nullptr; >> if (RD && >> RequireCompleteDeclContext(const_cast<CXXScopeSpec&>(SS), RD)) >> RD = nullptr; >> >> @@ -8444,7 +8456,7 @@ bool Sema::CheckUsingDeclQualifier(Sourc >> return true; >> >> if (getLangOpts().CPlusPlus11) { >> - // C++0x [namespace.udecl]p3: >> + // C++11 [namespace.udecl]p3: >> // In a using-declaration used as a member-declaration, the >> // nested-name-specifier shall name a base class of the class >> // being defined. >> >> Removed: >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp?rev=268593&view=auto >> >> ============================================================================== >> --- >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp >> (original) >> +++ >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp >> (removed) >> @@ -1,46 +0,0 @@ >> -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s >> -// C++0x N2914. >> - >> -struct B { >> - void f(char); >> - void g(char); >> - enum E { e }; >> - union { int x; }; >> -}; >> - >> -class C { >> - int g(); >> -}; >> - >> -class D2 : public B { >> - using B::f; >> - using B::e; >> - using B::x; >> - using C::g; // expected-error{{using declaration refers into 'C::', >> which is not a base class of 'D2'}} >> -}; >> - >> -namespace test1 { >> - struct Base { >> - int foo(); >> - }; >> - >> - struct Unrelated { >> - int foo(); >> - }; >> - >> - struct Subclass : Base { >> - }; >> - >> - namespace InnerNS { >> - int foo(); >> - } >> - >> - // We should be able to diagnose these without instantiation. >> - template <class T> struct C : Base { >> - using InnerNS::foo; // expected-error {{not a class}} >> - using Base::bar; // expected-error {{no member named 'bar'}} >> - using Unrelated::foo; // expected-error {{not a base class}} >> - using C::foo; // expected-error {{refers to its own class}} >> - using Subclass::foo; // expected-error {{not a base class}} >> - }; >> -} >> >> Copied: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp >> (from r268583, >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp) >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp?p2=cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp&p1=cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp&r1=268583&r2=268594&rev=268594&view=diff >> >> ============================================================================== >> --- >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp >> (original) >> +++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp Wed >> May 4 21:13:49 2016 >> @@ -1,22 +1,48 @@ >> +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s >> // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s >> -// C++0x N2914. >> +// RUN: %clang_cc1 -fsyntax-only -verify %s >> >> struct B { >> void f(char); >> void g(char); >> enum E { e }; >> union { int x; }; >> + >> + enum class EC { ec }; // expected-warning 0-1 {{C++11}} >> + >> + void f2(char); >> + void g2(char); >> + enum E2 { e2 }; >> + union { int x2; }; >> }; >> >> class C { >> int g(); >> }; >> >> +struct D : B {}; >> + >> class D2 : public B { >> using B::f; >> + using B::E; >> using B::e; >> using B::x; >> using C::g; // expected-error{{using declaration refers into 'C::', >> which is not a base class of 'D2'}} >> + >> + // These are valid in C++98 but not in C++11. >> + using D::f2; >> + using D::E2; >> + using D::e2; >> + using D::x2; >> +#if __cplusplus >= 201103L >> + // expected-error@-5 {{using declaration refers into 'D::', which is >> not a base class of 'D2'}} >> + // expected-error@-5 {{using declaration refers into 'D::', which is >> not a base class of 'D2'}} >> + // expected-error@-5 {{using declaration refers into 'D::', which is >> not a base class of 'D2'}} >> + // expected-error@-5 {{using declaration refers into 'D::', which is >> not a base class of 'D2'}} >> +#endif >> + >> + using B::EC; >> + using B::EC::ec; // expected-error {{not a class}} expected-warning >> 0-1 {{C++11}} >> }; >> >> namespace test1 { >> @@ -35,12 +61,22 @@ namespace test1 { >> int foo(); >> } >> >> + struct B : Base { >> + }; >> + >> // We should be able to diagnose these without instantiation. >> template <class T> struct C : Base { >> using InnerNS::foo; // expected-error {{not a class}} >> using Base::bar; // expected-error {{no member named 'bar'}} >> using Unrelated::foo; // expected-error {{not a base class}} >> - using C::foo; // expected-error {{refers to its own class}} >> - using Subclass::foo; // expected-error {{not a base class}} >> + >> + // In C++98, it's hard to see that these are invalid, because >> indirect >> + // references to base class members are permitted. >> + using C::foo; >> + using Subclass::foo; >> +#if __cplusplus >= 201103L >> + // expected-error@-3 {{refers to its own class}} >> + // expected-error@-3 {{not a base class}} >> +#endif >> }; >> } >> >> Removed: >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp?rev=268593&view=auto >> >> ============================================================================== >> --- >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp >> (original) >> +++ >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp >> (removed) >> @@ -1,8 +0,0 @@ >> -// RUN: %clang_cc1 -fsyntax-only -verify %s >> -// C++0x N2914. >> - >> -namespace A { >> - namespace B { } >> -} >> - >> -using A::B; // expected-error{{using declaration cannot refer to >> namespace}} >> >> Copied: >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp >> (from r268583, >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp) >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp?p2=cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp&p1=cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp&r1=268583&r2=268594&rev=268594&view=diff >> >> ============================================================================== >> --- >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp >> (original) >> +++ >> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp Wed >> May 4 21:13:49 2016 >> @@ -1,8 +1,7 @@ >> // RUN: %clang_cc1 -fsyntax-only -verify %s >> -// C++0x N2914. >> >> namespace A { >> namespace B { } >> } >> >> -using A::B; // expected-error{{using declaration cannot refer to >> namespace}} >> +using A::B; // expected-error{{using declaration cannot refer to a >> namespace}} >> >> Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=268594&r1=268593&r2=268594&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/CXX/drs/dr4xx.cpp (original) >> +++ cfe/trunk/test/CXX/drs/dr4xx.cpp Wed May 4 21:13:49 2016 >> @@ -702,8 +702,8 @@ namespace dr460 { // dr460: yes >> namespace X { namespace Q { int n; } } >> namespace Y { >> using X; // expected-error {{requires a qualified name}} >> - using dr460::X; // expected-error {{cannot refer to namespace}} >> - using X::Q; // expected-error {{cannot refer to namespace}} >> + using dr460::X; // expected-error {{cannot refer to a namespace}} >> + using X::Q; // expected-error {{cannot refer to a namespace}} >> } >> } >> >> >> Modified: cfe/trunk/test/SemaCXX/enum-scoped.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/enum-scoped.cpp?rev=268594&r1=268593&r2=268594&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/enum-scoped.cpp (original) >> +++ cfe/trunk/test/SemaCXX/enum-scoped.cpp Wed May 4 21:13:49 2016 >> @@ -298,8 +298,8 @@ namespace PR18044 { >> int E::*p; // expected-error {{does not point into a class}} >> using E::f; // expected-error {{no member named 'f'}} >> >> - using E::a; // ok! >> - E b = a; >> + using E::a; // expected-error {{using declaration cannot refer to a >> scoped enumerator}} >> + E b = a; // expected-error {{undeclared}} >> } >> >> namespace test11 { >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits