+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/49045
+ Core 1321
+ * tree.c (dependent_name): New.
+ (cp_tree_equal): Two calls with the same dependent name are
+ equivalent even if the overload sets are different.
+
2011-08-23 Jason Merrill <jason@redhat.com>
* tree.c (build_target_expr): Set TREE_CONSTANT on
|| TREE_CODE (x) == OVERLOAD);
}
+/* X is the CALL_EXPR_FN of a CALL_EXPR. If X represents a dependent name
+ (14.6.2), return the IDENTIFIER_NODE for that name. Otherwise, return
+ NULL_TREE. */
+
+static tree
+dependent_name (tree x)
+{
+ if (TREE_CODE (x) == IDENTIFIER_NODE)
+ return x;
+ if (TREE_CODE (x) != COMPONENT_REF
+ && is_overloaded_fn (x))
+ return DECL_NAME (get_first_fn (x));
+ return NULL_TREE;
+}
+
/* Returns true iff X is an expression for an overloaded function
whose type cannot be known without performing overload
resolution. */
{
tree arg1, arg2;
call_expr_arg_iterator iter1, iter2;
- if (!cp_tree_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+ /* 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)))
return false;
for (arg1 = first_call_expr_arg (t1, &iter1),
arg2 = first_call_expr_arg (t2, &iter2);
--- /dev/null
+// Core 1321
+// { dg-options -std=c++0x }
+// Two dependent names are equivalent even if the overload sets found by
+// phase 1 lookup are different. Merging them keeps the earlier set.
+
+int g1(int);
+template <class T> decltype(g1(T())) f1();
+int g1();
+template <class T> decltype(g1(T())) f1()
+{ return g1(T()); }
+int i1 = f1<int>(); // OK, g1(int) was declared before the first f1
+
+template <class T> decltype(g2(T())) f2();
+int g2(int);
+template <class T> decltype(g2(T())) f2() // { dg-error "g2. was not declared" }
+{ return g2(T()); }
+int i2 = f2<int>(); // { dg-error "no match" }
+
+int g3();
+template <class T> decltype(g3(T())) f3();
+int g3(int);
+template <class T> decltype(g3(T())) f3() // { dg-error "too many arguments" }
+{ return g3(T()); }
+int i3 = f3<int>(); // { dg-error "no match" }