PR c++/21682, implement DR 565
authorPaolo Carlini <paolo@gcc.gnu.org>
Mon, 2 Sep 2013 09:42:39 +0000 (09:42 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 2 Sep 2013 09:42:39 +0000 (09:42 +0000)
/cp
2013-09-02  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/21682, implement DR 565
* name-lookup.c (compparms_for_decl_and_using_decl): New.
(push_overloaded_decl_1, do_nonmember_using_decl): Use it.

/testsuite
2013-09-02  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/21682, implement DR 565
* g++.dg/template/using24.C: New.
* g++.dg/template/using25.C: Likewise.
* g++.dg/template/using26.C: Likewise.

From-SVN: r202163

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

index 433c12d174127e33c20d1bb1c4b0e1cdceda738a..7cafed9c3b547216d3ab9cb1a31d9fa3991168fb 100644 (file)
@@ -1,3 +1,9 @@
+2013-09-02  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/21682, implement DR 565
+       * name-lookup.c (compparms_for_decl_and_using_decl): New.
+       (push_overloaded_decl_1, do_nonmember_using_decl): Use it.
+
 2013-08-30  Marek Polacek  <polacek@redhat.com>
 
        * typeck.c (cp_build_binary_op): Add division by zero and shift
index b09e85bcb66487a8c0764c367a080fa189e18a73..025a03cd9fa61e16a0eb979950c9fb996b921602 100644 (file)
@@ -2267,6 +2267,27 @@ pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
   return ret;
 }
 
+/* Helper function for push_overloaded_decl_1 and do_nonmember_using_decl.
+   Compares the parameter-type-lists of DECL1 and DECL2 and returns false
+   if they are different.  If the DECLs are template functions, the return
+   types and the template parameter lists are compared too (DR 565).  */
+
+static bool
+compparms_for_decl_and_using_decl (tree decl1, tree decl2)
+{
+  if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (decl1)),
+                 TYPE_ARG_TYPES (TREE_TYPE (decl2))))
+    return false;
+
+  if (! DECL_FUNCTION_TEMPLATE_P (decl1)
+      || ! DECL_FUNCTION_TEMPLATE_P (decl2))
+    return true;
+
+  return (comp_template_parms (DECL_TEMPLATE_PARMS (decl1),
+                              DECL_TEMPLATE_PARMS (decl2))
+         && same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
+                         TREE_TYPE (TREE_TYPE (decl2))));
+}
 
 /* DECL is a FUNCTION_DECL for a non-member function, which may have
    other definitions already in place.  We get around this by making
@@ -2324,8 +2345,7 @@ push_overloaded_decl_1 (tree decl, int flags, bool is_friend)
 
              if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
                  && !(flags & PUSH_USING)
-                 && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
-                               TYPE_ARG_TYPES (TREE_TYPE (decl)))
+                 && compparms_for_decl_and_using_decl (fn, decl)
                  && ! decls_match (fn, decl))
                diagnose_name_conflict (decl, fn);
 
@@ -2561,8 +2581,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
                    break;
                  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))))
+                 else if (compparms_for_decl_and_using_decl (new_fn, old_fn))
                    {
                      gcc_assert (!DECL_ANTICIPATED (old_fn)
                                  || DECL_HIDDEN_FRIEND_P (old_fn));
index 7ff5882d6b948bde77a33ad756910a5b06f7f58d..c87b30ac4b0c5dff28060618e8ba9e40a9383c66 100644 (file)
@@ -1,4 +1,11 @@
-2013-09-01  Jan Hubicka  <jh@suse.cz>  
+2013-09-02  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/21682, implement DR 565
+       * g++.dg/template/using24.C: New.
+       * g++.dg/template/using25.C: Likewise.
+       * g++.dg/template/using26.C: Likewise.
+
+2013-09-01  Jan Hubicka  <jh@suse.cz>
 
        * g++.dg/ipa/devirt-15.C: New testcase.
 
diff --git a/gcc/testsuite/g++.dg/template/using24.C b/gcc/testsuite/g++.dg/template/using24.C
new file mode 100644 (file)
index 0000000..c3cdf93
--- /dev/null
@@ -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); }
diff --git a/gcc/testsuite/g++.dg/template/using25.C b/gcc/testsuite/g++.dg/template/using25.C
new file mode 100644 (file)
index 0000000..6f4a7de
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/21682
+
+namespace one {
+  template<typename T> void fun(T);
+}
+
+using one::fun;
+
+template<typename T> void fun(T);  // { dg-error "conflicts" }
+
+template<typename T> void funr(T);
+
+namespace oner {
+  template<typename T> void funr(T);
+}
+
+using oner::funr;  // { dg-error "conflicts" }
diff --git a/gcc/testsuite/g++.dg/template/using26.C b/gcc/testsuite/g++.dg/template/using26.C
new file mode 100644 (file)
index 0000000..ca21857
--- /dev/null
@@ -0,0 +1,49 @@
+// PR c++/21682
+
+namespace one {
+  template<typename T> int bar1(T);
+}
+
+using one::bar1;
+
+template<typename T> void bar1(T);
+
+template<typename T> void bar1r(T);
+
+namespace oner {
+  template<typename T> int bar1r(T);
+}
+
+using oner::bar1r;
+
+namespace two {
+  template<typename T, typename U> void bar2(T);
+}
+
+using two::bar2;
+
+template<typename T> void bar2(T);
+
+template<typename T> void bar2r(T);
+
+namespace twor {
+  template<typename T, typename U> void bar2r(T);
+}
+
+using twor::bar2r;
+
+namespace three {
+  template<int i> void bar3();
+}
+
+using three::bar3;
+
+template<typename T> void bar3();
+
+template<typename T> void bar3r();
+
+namespace threer {
+  template<int i> void bar3r();
+}
+
+using threer::bar3r;