re PR c++/20420 (Incorrectly Accepts double declarations)
authorPaolo Carlini <paolo.carlini@oracle.com>
Thu, 23 Aug 2012 09:44:08 +0000 (09:44 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 23 Aug 2012 09:44:08 +0000 (09:44 +0000)
/cp
2012-08-23  Paolo Carlini  <paolo.carlini@oracle.com>

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

/testsuite
2012-08-23  Paolo Carlini  <paolo.carlini@oracle.com>

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

From-SVN: r190618

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/using53.C [new file with mode: 0644]

index 0d9de13f74ba060867f342d412a8bf50d30a0d9f..58e6e1f5bdfd086c8ce5623de5206179cad1ca75 100644 (file)
@@ -1,3 +1,11 @@
+2012-08-23  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/20420
+       * name-lookup.c (supplement_binding_1): Handle specially enums
+       only in class templates.
+       (validate_nonmember_using_decl): Enforce 7.3.3/10 about duplicate
+       using declarations at function scope.
+
 2012-08-21  Richard Guenther  <rguenther@suse.de>
 
        * cp-tree.h (TREE_INDIRECT_USING): Use TREE_LANG_FLAG_0 accessor.
index f8dbfa1b628504973cf8d0efbee9da51c7e77b9d..22bc5e7c0060d48ae82348c6efee0d133ef0cc60 100644 (file)
@@ -441,7 +441,8 @@ supplement_binding_1 (cxx_binding *binding, tree decl)
             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)))
@@ -2420,7 +2421,15 @@ validate_nonmember_using_decl (tree decl, tree scope, tree name)
   gcc_assert (DECL_P (decl));
 
   /* Make a USING_DECL.  */
-  return push_using_decl (scope, name);
+  tree using_decl = push_using_decl (scope, name);
+
+  if (using_decl == NULL_TREE
+      && at_function_scope_p ()
+      && TREE_CODE (decl) == VAR_DECL)
+    /* C++11 7.3.3/10.  */
+    error ("%qD is already declared in this scope", name);
+  
+  return using_decl;
 }
 
 /* Process local and global using-declarations.  */
index 6f8cae84bd11475d58f879fcf7b9b22a85e6d530..7e011ec2cbdfcd03200cf784abb7f601e2bb8526 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-23  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/20420
+       * g++.dg/lookup/using53.C: New.
+
 2012-08-23  Georg-Johann Lay  <avr@gjlay.de>
 
        * gcc.dg/fixed-point/convert.c: Split into manageable parts:
diff --git a/gcc/testsuite/g++.dg/lookup/using53.C b/gcc/testsuite/g++.dg/lookup/using53.C
new file mode 100644 (file)
index 0000000..a108b50
--- /dev/null
@@ -0,0 +1,53 @@
+// 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" }
+};
+
+template<typename T>
+class BT
+{
+protected:
+  enum E { E1, E2, E3 };
+  struct S { int i; E e; };
+};
+
+template<typename T>
+class DT : private BT<T>
+{
+public:
+  using BT<T>::E;   // { dg-message "previous" }
+  using BT<T>::S;   // { dg-message "previous" }
+
+private:
+  enum E {};        // { dg-error "conflicts" }
+  struct S {};      // { dg-error "conflicts" }
+};
+
+template class DT<int>;
+
+namespace N
+{
+  int i;
+}
+
+void
+f ()
+{
+  using N::i;
+  using N::i;       // { dg-error "declared" }
+}