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