From f7d605acaacc68d4c50af8e4ca3e1d30c3f13a80 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 23 Aug 2011 12:03:44 -0400 Subject: [PATCH] re PR c++/49045 ([C++0x] unexpected "different exception specifier" error with noexcept) 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. From-SVN: r177998 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/tree.c | 22 +++++++++++++++++++++- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/cpp0x/overload2.C | 24 ++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/overload2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 23a63ce5a1b..4870f3570fe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2011-08-23 Jason Merrill + + 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 * tree.c (build_target_expr): Set TREE_CONSTANT on diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 00598ce6069..13421a4e7ab 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1450,6 +1450,21 @@ is_overloaded_fn (tree x) || 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. */ @@ -2187,7 +2202,12 @@ cp_tree_equal (tree t1, tree t2) { 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a85caca0ff5..bacec37e9ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-08-23 Jason Merrill + + PR c++/49045 + Core 1321 + * g++.dg/cpp0x/overload2.C: New. + 2011-08-23 Jason Merrill Core 903 diff --git a/gcc/testsuite/g++.dg/cpp0x/overload2.C b/gcc/testsuite/g++.dg/cpp0x/overload2.C new file mode 100644 index 00000000000..ff8ad22bea6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/overload2.C @@ -0,0 +1,24 @@ +// 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 decltype(g1(T())) f1(); +int g1(); +template decltype(g1(T())) f1() +{ return g1(T()); } +int i1 = f1(); // OK, g1(int) was declared before the first f1 + +template decltype(g2(T())) f2(); +int g2(int); +template decltype(g2(T())) f2() // { dg-error "g2. was not declared" } +{ return g2(T()); } +int i2 = f2(); // { dg-error "no match" } + +int g3(); +template decltype(g3(T())) f3(); +int g3(int); +template decltype(g3(T())) f3() // { dg-error "too many arguments" } +{ return g3(T()); } +int i3 = f3(); // { dg-error "no match" }