Hi,

this testcase triggers the gcc_assert in initialize_reference because the conv returned by reference_binding has conv->kind == ck_ambig.

Before the crash, the diagnostic about ambiguous conversion is produced by build_user_type_conversion_1, and it seems that in this case too we can safely return error_mark_node, as happens when it's called by build_user_type_conversion instead of direct_reference_binding.

Tested x86_64-linux.

Thanks,
Paolo.

///////////////////

/cp
2013-07-29  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/57948
        * call.c (initialize_reference): Don't crash when reference_binding
        returns a conv with conv->kind == ck_ambig.

/testsuite
2013-07-29  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/57948
        * g++.dg/conversion/ambig2.C: New.
Index: cp/call.c
===================================================================
--- cp/call.c   (revision 201313)
+++ cp/call.c   (working copy)
@@ -9282,11 +9282,15 @@ initialize_reference (tree type, tree expr,
       return error_mark_node;
     }
 
-  gcc_assert (conv->kind == ck_ref_bind);
+  if (conv->kind == ck_ref_bind)
+    /* Perform the conversion.  */
+    expr = convert_like (conv, expr, complain);
+  else if (conv->kind == ck_ambig)
+    /* We gave an error in build_user_type_conversion_1.  */
+    expr = error_mark_node;
+  else
+    gcc_unreachable ();
 
-  /* Perform the conversion.  */
-  expr = convert_like (conv, expr, complain);
-
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
Index: testsuite/g++.dg/conversion/ambig2.C
===================================================================
--- testsuite/g++.dg/conversion/ambig2.C        (revision 0)
+++ testsuite/g++.dg/conversion/ambig2.C        (working copy)
@@ -0,0 +1,18 @@
+// PR c++/57948
+
+struct Base {   };
+struct Derived : Base
+{
+  struct Derived2 : Base
+  {
+    struct ConvertibleToBothDerivedRef
+    {
+      operator Derived&();
+      operator Derived2&();
+      void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both)
+      {
+       Base &br1 = both; // { dg-error "ambiguous" }
+      }
+    };
+  };
+};

Reply via email to