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