conv_binds_ref_to_prvalue was expecting that if a user-defined
conversion uses a conversion function returning a reference, the
conversion will have reference type.  This wasn't the case, because
build_user_type_conversion_1 strips the reference from the return type
to get the type of the conversion.

It seems to me that in the case of direct binding to a reference, we
want the conversion to have reference type.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 819e3be84751834a5e70df910f1d1726ea1b82f5
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Apr 4 20:27:29 2018 -0400

            PR c++/85215 - ICE with copy-init from conversion.
    
            * call.c (merge_conversion_sequences): Fix type of direct binding
            sequence.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7c99e8ad910..f2ada2768de 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3642,6 +3642,12 @@ merge_conversion_sequences (conversion *user_seq, conversion *std_seq)
 	(*t)->bad_p = true;
     }
 
+  if ((*t)->rvaluedness_matches_p)
+    /* We're binding a reference directly to the result of the conversion.
+       build_user_type_conversion_1 stripped the REFERENCE_TYPE from the return
+       type, but we want it back.  */
+    user_seq->type = TREE_TYPE (TREE_TYPE (user_seq->cand->fn));
+
   /* Replace the identity conversion with the user conversion
      sequence.  */
   *t = user_seq;
diff --git a/gcc/testsuite/g++.dg/cpp1z/elide3.C b/gcc/testsuite/g++.dg/cpp1z/elide3.C
new file mode 100644
index 00000000000..ca4d24708a8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/elide3.C
@@ -0,0 +1,15 @@
+// PR c++/85215
+// { dg-do compile { target c++11 } }
+
+template <typename _Tp> struct vector {
+  vector(vector &&) noexcept;
+};
+
+template <typename T> struct any_container {
+  operator vector<T> &&();
+};
+
+void f (any_container<int> c)
+{
+  vector<int> shape (c);
+}

Reply via email to