re PR c++/32019 (Conditional operator ?: and ambiguous convertions)
authorJason Merrill <jason@redhat.com>
Fri, 9 May 2014 18:15:57 +0000 (14:15 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 9 May 2014 18:15:57 +0000 (14:15 -0400)
PR c++/32019
* call.c (build_conditional_expr_1): Improve ambiguity diagnostic.

PR c++/54348
* call.c (build_conditional_expr_1): If overload resolution finds
no match, just say "different types".

From-SVN: r210282

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/cpp0x/explicit3.C
gcc/testsuite/g++.dg/expr/cond10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/expr/cond11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/expr/cond13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/crash41.C

index 232ceec..6bddd49 100644 (file)
@@ -1,5 +1,12 @@
 2014-05-09  Jason Merrill  <jason@redhat.com>
 
+       PR c++/54348
+       * call.c (build_conditional_expr_1): If overload resolution finds
+       no match, just say "different types".
+
+       PR c++/32019
+       * call.c (build_conditional_expr_1): Improve ambiguity diagnostic.
+
        PR c++/22434
        * call.c (build_conditional_expr_1): Don't try to pool cv-quals
        if we didn't find a conversion.
index 691e9e3..cff7ef3 100644 (file)
@@ -4710,8 +4710,16 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
          || (conv3 && conv3->kind == ck_ambig))
        {
          if (complain & tf_error)
-           error_at (loc, "operands to ?: have different types %qT and %qT",
-                     arg2_type, arg3_type);
+           {
+             error_at (loc, "operands to ?: have different types %qT and %qT",
+                       arg2_type, arg3_type);
+             if (conv2 && !conv2->bad_p && conv3 && !conv3->bad_p)
+               inform (loc, "  and each type can be converted to the other");
+             else if (conv2 && conv2->kind == ck_ambig)
+               convert_like (conv2, arg2, complain);
+             else
+               convert_like (conv3, arg3, complain);
+           }
          result = error_mark_node;
        }
       else if (conv2 && !conv2->bad_p)
@@ -4818,10 +4826,8 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
       if (!any_viable_p)
        {
           if (complain & tf_error)
-            {
-              op_error (loc, COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
-              print_z_candidates (loc, candidates);
-            }
+           error_at (loc, "operands to ?: have different types %qT and %qT",
+                     arg2_type, arg3_type);
          return error_mark_node;
        }
       cand = tourney (candidates, complain);
index 678076c..6318ade 100644 (file)
@@ -45,6 +45,6 @@ int main()
   f(a);                                // { dg-error "" }
   B b2 = { a };                        // { dg-error "" }
   a + true;                    // { dg-error "5:no match" }
-  b ? a : true;                        // { dg-error "5:no match" }
-  a ? a : true;                        // { dg-error "5:no match" }
+  b ? a : true;                        // { dg-error "5:?:" }
+  a ? a : true;                        // { dg-error "5:?:" }
 }
diff --git a/gcc/testsuite/g++.dg/expr/cond10.C b/gcc/testsuite/g++.dg/expr/cond10.C
new file mode 100644 (file)
index 0000000..892576f
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/32019
+
+struct C
+{
+  C(const char *);
+  operator const char *();
+};
+
+extern C c;
+extern const char * s;
+
+void
+foo (bool b)
+{
+  b ? c : s;                   // { dg-error "?:" }
+  // { dg-message "convert" "" { target *-*-* } 15 }
+}
diff --git a/gcc/testsuite/g++.dg/expr/cond11.C b/gcc/testsuite/g++.dg/expr/cond11.C
new file mode 100644 (file)
index 0000000..7bd122d
--- /dev/null
@@ -0,0 +1,20 @@
+struct A;
+struct C
+{
+  operator A();
+};
+
+struct A
+{
+  A(C);
+};
+
+extern A a;
+extern C c;
+
+void
+foo (bool b)
+{
+  b ? c : a;                   // { dg-error "?:" }
+  // { dg-message "ambiguous" "" { target *-*-* } 18 }
+}
diff --git a/gcc/testsuite/g++.dg/expr/cond13.C b/gcc/testsuite/g++.dg/expr/cond13.C
new file mode 100644 (file)
index 0000000..90ae904
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/54348
+
+struct A {} a;
+struct B {} b;
+
+void f()
+{
+    false ? a : b;             // { dg-error "different types" }
+}
index 746dbbc..c14fbad 100644 (file)
@@ -5,4 +5,4 @@ struct A
   A(int)(); // { dg-error "declared" }
 };
 
-template<int> void foo(bool b, A a) { b ? a : 0; } // { dg-error "no match" }
+template<int> void foo(bool b, A a) { b ? a : 0; } // { dg-error "?:" }