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