r268594 - Fix implementation of C++'s restrictions on using-declarations referring to enumerators:
Reid Kleckner via cfe-commits
cfe-commits at lists.llvm.org
Thu May 5 10:40:53 PDT 2016
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 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/b9e4f91b/attachment-0001.html>
More information about the cfe-commits
mailing list