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. 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