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

Reply via email to