aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-01-24 14:07:24 -0500
committerJason Merrill <jason@gcc.gnu.org>2012-01-24 14:07:24 -0500
commitc873934cd90496aa07712b257b6ae6e8027d952f (patch)
tree5dc59caab5d354a1061165ba45e9184371131f42
parent5535633407a3c84b4f19b9c2f88be92cb51ba8e3 (diff)
downloadgcc-c873934cd90496aa07712b257b6ae6e8027d952f.zip
gcc-c873934cd90496aa07712b257b6ae6e8027d952f.tar.gz
gcc-c873934cd90496aa07712b257b6ae6e8027d952f.tar.bz2
re PR c++/51973 ([C++11] Template parameter deduction fails for overloaded functions when template parameters have defaulted arguments)
PR c++/51973 * tree.c (called_fns_equal): Check template args. (cp_tree_equal): Call it. From-SVN: r183487
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/tree.c58
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae31.C13
4 files changed, 60 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6dbb433..a79320c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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>
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index cf39800..b80b52a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2fdb674..b34ea63a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..ea151fe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae31.C
@@ -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>();
+}