PR c++/51973
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Jan 2012 19:07:24 +0000 (19:07 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Jan 2012 19:07:24 +0000 (19:07 +0000)
* tree.c (called_fns_equal): Check template args.
(cp_tree_equal): Call it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183487 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/sfinae31.C [new file with mode: 0644]

index 6dbb433..a79320c 100644 (file)
@@ -1,3 +1,9 @@
+2012-01-24  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51973
+       * tree.c (called_fns_equal): Check template args.
+       (cp_tree_equal): Call it.
+
 2012-01-24  Aldy Hernandez  <aldyh@redhat.com>
            Patrick Marlier  <patrick.marlier@gmail.com>
 
index cf39800..b80b52a 100644 (file)
@@ -2174,6 +2174,33 @@ decl_anon_ns_mem_p (const_tree decl)
     }
 }
 
+/* Subroutine of cp_tree_equal: t1 and t2 are the CALL_EXPR_FNs of two
+   CALL_EXPRS.  Return whether they are equivalent.  */
+
+static bool
+called_fns_equal (tree t1, tree t2)
+{
+  /* Core 1321: dependent names are equivalent even if the overload sets
+     are different.  But do compare explicit template arguments.  */
+  tree name1 = dependent_name (t1);
+  tree name2 = dependent_name (t2);
+  if (name1 || name2)
+    {
+      tree targs1 = NULL_TREE, targs2 = NULL_TREE;
+
+      if (name1 != name2)
+       return false;
+
+      if (TREE_CODE (t1) == TEMPLATE_ID_EXPR)
+       targs1 = TREE_OPERAND (t1, 1);
+      if (TREE_CODE (t2) == TEMPLATE_ID_EXPR)
+       targs2 = TREE_OPERAND (t2, 1);
+      return cp_tree_equal (targs1, targs2);
+    }
+  else
+    return cp_tree_equal (t1, t2);
+}
+
 /* Return truthvalue of whether T1 is the same tree structure as T2.
    Return 1 if they are the same. Return 0 if they are different.  */
 
@@ -2261,12 +2288,7 @@ cp_tree_equal (tree t1, tree t2)
       {
        tree arg1, arg2;
        call_expr_arg_iterator iter1, iter2;
-       /* Core 1321: dependent names are equivalent even if the
-          overload sets are different.  */
-       tree name1 = dependent_name (CALL_EXPR_FN (t1));
-       tree name2 = dependent_name (CALL_EXPR_FN (t2));
-       if (!(name1 && name2 && name1 == name2)
-           && !cp_tree_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+       if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
          return false;
        for (arg1 = first_call_expr_arg (t1, &iter1),
               arg2 = first_call_expr_arg (t2, &iter2);
@@ -2354,26 +2376,18 @@ cp_tree_equal (tree t1, tree t2)
                              TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
 
     case TEMPLATE_ID_EXPR:
+      return (cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
+             && cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)));
+
+    case TREE_VEC:
       {
        unsigned ix;
-       tree vec1, vec2;
-
-       if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+       if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
          return false;
-       vec1 = TREE_OPERAND (t1, 1);
-       vec2 = TREE_OPERAND (t2, 1);
-
-       if (!vec1 || !vec2)
-         return !vec1 && !vec2;
-
-       if (TREE_VEC_LENGTH (vec1) != TREE_VEC_LENGTH (vec2))
-         return false;
-
-       for (ix = TREE_VEC_LENGTH (vec1); ix--;)
-         if (!cp_tree_equal (TREE_VEC_ELT (vec1, ix),
-                             TREE_VEC_ELT (vec2, ix)))
+       for (ix = TREE_VEC_LENGTH (t1); ix--;)
+         if (!cp_tree_equal (TREE_VEC_ELT (t1, ix),
+                             TREE_VEC_ELT (t2, ix)))
            return false;
-
        return true;
       }
 
index 2fdb674..b34ea63 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-24  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51973
+       * g++.dg/cpp0x/sfinae31.C: New.
+
 2012-01-24  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gcc.dg/memcpy-4.c: Don't expect /s on MEMs.
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae31.C b/gcc/testsuite/g++.dg/cpp0x/sfinae31.C
new file mode 100644 (file)
index 0000000..ea151fe
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/51973
+// { dg-options -std=c++0x }
+
+template <class T>
+void f(T t) { };
+
+template <class T> decltype(f<T>(0)) g();
+template <class T> decltype(f<T*>(0)) g();
+
+int main()
+{
+  g<void>();
+}