Hi,
this patch resolves the bug by implementing the resolution of DR 565
(DRWP): for template functions, in order to establish that the program
is ill-formed we want to check return type and template parameter list
too. Thus, in practice, we want to accept the reduced testcase which
came with c++/21682 (using24.C) and reject the testcase which I
discussed in DR 565 (using25.C) (*)
Booted & tested x86_64-linux.
Thanks!
Paolo.
(*) Likewise current clang.
//////////////////////////
/cp
2013-09-01 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/21682, implement DR 565
* name-lookup.c (do_nonmember_using_decl): For template function,
check return type and template parameter list too.
/testsuite
2013-09-01 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/21682, implement DR 565
* g++.dg/template/using24.C: New.
* g++.dg/template/using25.C: Likewise.
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c (revision 202141)
+++ cp/name-lookup.c (working copy)
@@ -2562,7 +2562,20 @@ do_nonmember_using_decl (tree scope, tree name, tr
else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1))
continue; /* this is a using decl */
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn)))
+ /* DR 565: If a function template declaration in
+ namespace scope has the same name, parameter-
+ type-list, return type, and template parameter
+ list as a function template introduced by a
+ using-declaration, the program is ill-formed. */
+ && (TREE_CODE (new_fn) != TEMPLATE_DECL
+ || TREE_CODE (old_fn) != TEMPLATE_DECL
+ || (comp_template_parms
+ (DECL_TEMPLATE_PARMS (new_fn),
+ DECL_TEMPLATE_PARMS (old_fn))
+ && (same_type_p
+ (TREE_TYPE (TREE_TYPE (new_fn)),
+ TREE_TYPE (TREE_TYPE (old_fn)))))))
{
gcc_assert (!DECL_ANTICIPATED (old_fn)
|| DECL_HIDDEN_FRIEND_P (old_fn));
Index: testsuite/g++.dg/template/using24.C
===================================================================
--- testsuite/g++.dg/template/using24.C (revision 0)
+++ testsuite/g++.dg/template/using24.C (working copy)
@@ -0,0 +1,30 @@
+// PR c++/21682
+
+template <class T>
+struct t
+{
+ typedef typename T::type type;
+};
+template<> class t<int>{};
+
+template <class T> struct t1{ };
+template<> struct t1<int>
+{
+ typedef int type;
+};
+
+namespace name1
+{
+ template <class S> typename t<S>::type begin(S const& s);
+ namespace name2
+ {
+ template <class S> typename t1<S>::type begin(S const& s);
+ }
+ using name2::begin;
+}
+
+/* Test calling the function. */
+int f(int a) { return name1::begin(a); }
+
+struct aa { typedef double type; };
+double g(aa t) { return name1::begin(t); }
Index: testsuite/g++.dg/template/using25.C
===================================================================
--- testsuite/g++.dg/template/using25.C (revision 0)
+++ testsuite/g++.dg/template/using25.C (working copy)
@@ -0,0 +1,9 @@
+// PR c++/21682
+
+namespace one {
+ template<typename T> void fun(T);
+}
+
+using one::fun;
+
+template<typename T> void fun(T); // { dg-error "conflicts" }