aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-08-23 12:03:44 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-08-23 12:03:44 -0400
commitf7d605acaacc68d4c50af8e4ca3e1d30c3f13a80 (patch)
treed88cc7f6a94052edc9790e4eabd3f202d48474db
parent30fdd4f2bf86abb827cd82c25723cd08acb9fb26 (diff)
downloadgcc-f7d605acaacc68d4c50af8e4ca3e1d30c3f13a80.zip
gcc-f7d605acaacc68d4c50af8e4ca3e1d30c3f13a80.tar.gz
gcc-f7d605acaacc68d4c50af8e4ca3e1d30c3f13a80.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/tree.c22
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/overload2.C24
4 files changed, 59 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 23a63ce..4870f35 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
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
literal TARGET_EXPR if the value is constant.
* typeck2.c (build_functional_cast): Don't set it here.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 00598ce..13421a4 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 a85caca..bacec37 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2011-08-23 Jason Merrill <jason@redhat.com>
+ PR c++/49045
+ Core 1321
+ * g++.dg/cpp0x/overload2.C: New.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
Core 903
* g++.dg/cpp0x/constexpr-nullptr.C: Now ill-formed.
diff --git a/gcc/testsuite/g++.dg/cpp0x/overload2.C b/gcc/testsuite/g++.dg/cpp0x/overload2.C
new file mode 100644
index 0000000..ff8ad22
--- /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 <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" }