re PR c++/49045 ([C++0x] unexpected "different exception specifier" error with noexcept)
authorJason Merrill <jason@redhat.com>
Tue, 23 Aug 2011 16:03:44 +0000 (12:03 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 23 Aug 2011 16:03:44 +0000 (12:03 -0400)
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
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/overload2.C [new file with mode: 0644]

index 23a63ce5a1bbfbc09bc8c2d5dd5f9a97a5f18460..4870f3570fe66b0e9e0e40c9a1ce1fe13a30878e 100644 (file)
@@ -1,3 +1,11 @@
+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
index 00598ce60699f5fe8582aa037b5e11cda1548aa6..13421a4e7ab2d21c29c42e1a1aff1f8bfe64673e 100644 (file)
@@ -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);
index a85caca0ff587e7f22f31729d0ae45647d1f33cb..bacec37e9ace6141cd691e96d6c0a9e47232bb28 100644 (file)
@@ -1,3 +1,9 @@
+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
diff --git a/gcc/testsuite/g++.dg/cpp0x/overload2.C b/gcc/testsuite/g++.dg/cpp0x/overload2.C
new file mode 100644 (file)
index 0000000..ff8ad22
--- /dev/null
@@ -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" }