Hi,

yesterday I had a look to this old PR and noticed that we are almost doing already the right thing for the original testcase: we are for classes, but we ICE (something recent) for enums. The latter issue seems easy to fix: handle specially enums at the beginning of supplement_binding_1 only when the comment says, that is in templates (otherwise we hit an assert in dependent_type_p).

Then, Comment #4 in the audit trail added a case of duplicate using declaration which we should also reject, involving VAR_DECLs at function scope (C++11 7.3.3/10). Seems also easy to fix, by checking the return value of validate_nonmember_using_decl at the beginning of do_local_using_decl and erroring out if it's null.

Tested x86_64-linux.

Thanks,
Paolo.

///////////////////////////


/cp
2012-08-22  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/20420
        * name-lookup.c (supplement_binding_1): Handle specially enums
        only in class templates. 
        (do_local_using_decl): Enforce 7.3.3/10 about duplicate using
        declarations at function scope.

/testsuite
2012-08-22  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/20420
        * g++.dg/lookup/using53.C: New.


Index: testsuite/g++.dg/lookup/using53.C
===================================================================
--- testsuite/g++.dg/lookup/using53.C   (revision 0)
+++ testsuite/g++.dg/lookup/using53.C   (revision 0)
@@ -0,0 +1,31 @@
+// PR c++/20420
+
+class B
+{
+protected:
+  enum E { E1, E2, E3 };
+  struct S { int i; E e; };
+};
+
+class D : private B
+{
+public:
+  using B::E;       // { dg-message "previous" }
+  using B::S;       // { dg-message "previous" }
+
+private:
+  enum E {};        // { dg-error "conflicts" }
+  struct S {};      // { dg-error "conflicts" }
+};
+
+namespace N
+{
+  int i;
+}
+
+void
+f ()
+{
+  using N::i;
+  using N::i;       // { dg-error "declared" }
+}
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c    (revision 190590)
+++ cp/name-lookup.c    (working copy)
@@ -441,7 +441,8 @@ supplement_binding_1 (cxx_binding *binding, tree d
             template in order to handle late matching of underlying
             type on an opaque-enum-declaration followed by an
             enum-specifier.  */
-         || (TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
+         || (processing_template_decl
+             && TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
              && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE
              && (dependent_type_p (ENUM_UNDERLYING_TYPE
                                    (TREE_TYPE (target_decl)))
@@ -2581,7 +2582,12 @@ do_local_using_decl (tree decl, tree scope, tree n
 
   decl = validate_nonmember_using_decl (decl, scope, name);
   if (decl == NULL_TREE)
-    return;
+    {
+      /* C++11 7.3.3/10.  */
+      if (TREE_CODE (orig_decl) == VAR_DECL)
+       error ("%qD is already declared in this scope", name);
+      return;
+    }
 
   if (building_stmt_list_p ()
       && at_function_scope_p ())

Reply via email to