r268594 - Fix implementation of C++'s restrictions on using-declarations referring to enumerators:
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Thu May 5 11:15:47 PDT 2016
On Thu, May 5, 2016 at 10:40 AM, Reid Kleckner <rnk at 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 at 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 at -5 {{using declaration refers into 'D::', which is
>> not a base class of 'D2'}}
>> + // expected-error at -5 {{using declaration refers into 'D::', which is
>> not a base class of 'D2'}}
>> + // expected-error at -5 {{using declaration refers into 'D::', which is
>> not a base class of 'D2'}}
>> + // expected-error at -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 at -3 {{refers to its own class}}
>> + // expected-error at -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 at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160505/9b4e3191/attachment-0001.html>
More information about the cfe-commits
mailing list