PR c++/87109, wrong overload with ref-qualifiers.
authorMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 5 Sep 2018 21:17:47 +0000 (21:17 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 5 Sep 2018 21:17:47 +0000 (21:17 +0000)
* call.c (build_user_type_conversion_1): Use NULL instead of 0.  Bail
out if performing the maybe-rvalue overload resolution and a conversion
function is getting called.

* g++.dg/cpp0x/ref-qual19.C: New test.

From-SVN: r264132

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/ref-qual19.C [new file with mode: 0644]

index 498b1fa9252b5bb982d80885da0107816412caea..b4ec9f4b449500d323d903620ce2e73254cd87b8 100644 (file)
@@ -1,4 +1,11 @@
-2018-09-05   Pádraig Brady p@draigbrady.com
+2018-09-05  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/87109, wrong overload with ref-qualifiers.
+       * call.c (build_user_type_conversion_1): Use NULL instead of 0.  Bail
+       out if performing the maybe-rvalue overload resolution and a conversion
+       function is getting called.
+
+2018-09-05  Pádraig Brady  <p@draigbrady.com>
 
        PR c++/87185
        * lambda.c (prune_lambda_captures): Protect against const_vars.get
index a1567026975f6ef75f2ed9d82a063e1e66f5172d..942b2c204be32facab649dcc1a689b6c1e1223de 100644 (file)
@@ -3971,7 +3971,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
     }
 
   cand = tourney (candidates, complain);
-  if (cand == 0)
+  if (cand == NULL)
     {
       if (complain & tf_error)
        {
@@ -4014,6 +4014,12 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
   if (cand->viable == -1)
     conv->bad_p = true;
 
+  /* We're performing the maybe-rvalue overload resolution and
+     a conversion function is in play.  This isn't going to work
+     because we would not end up with a suitable constructor.  */
+  if ((flags & LOOKUP_PREFER_RVALUE) && !DECL_CONSTRUCTOR_P (cand->fn))
+    return NULL;
+
   /* Remember that this was a list-initialization.  */
   if (flags & LOOKUP_NO_NARROWING)
     conv->check_narrowing = true;
index 6936dd543f37de26b699552fa084686190499b37..a736ccf999a2aafd2c12eeb893db81ed6299f94b 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-05  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/87109, wrong overload with ref-qualifiers.
+       * g++.dg/cpp0x/ref-qual19.C: New test.
+
 2018-09-05  Bernhard Reutner-Fischer  <aldot@gcc.gnu.org>
 
        PR testsuite/52665
diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual19.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual19.C
new file mode 100644 (file)
index 0000000..8494b83
--- /dev/null
@@ -0,0 +1,117 @@
+// PR c++/87109
+// { dg-do run { target c++11 } }
+
+#include <utility>
+
+struct C { int i; };
+struct D { int i; };
+
+struct A {
+  int j;
+  operator C() & { return { 1 }; }
+  operator C() && { return { 2 }; }
+};
+
+struct B : public A {
+  operator D() & { return { 3 }; }
+  operator D() && { return { 4 }; }
+};
+
+C
+f (A a)
+{
+  return a;
+}
+
+C
+f2 (A a)
+{
+  return std::move (a);
+}
+
+C
+f3 ()
+{
+  A a;
+  return a;
+}
+
+C
+f4 ()
+{
+  A a;
+  return std::move (a);
+}
+
+C
+f5 ()
+{
+  return A();
+}
+
+D
+f6 (B b)
+{
+  return b;
+}
+
+D
+f7 (B b)
+{
+  return std::move (b);
+}
+
+D
+f8 ()
+{
+  B b;
+  return b;
+}
+
+D
+f9 ()
+{
+  B b;
+  return std::move (b);
+}
+
+D
+f10 ()
+{
+  return B();
+}
+
+int
+main ()
+{
+  C c1 = f (A());
+  if (c1.i != 1)
+    __builtin_abort ();
+  C c2 = f2 (A());
+  if (c2.i != 2)
+    __builtin_abort ();
+  C c3 = f3 ();
+  if (c3.i != 1)
+    __builtin_abort ();
+  C c4 = f4 ();
+  if (c4.i != 2)
+    __builtin_abort ();
+  C c5 = f5 ();
+  if (c5.i != 2)
+    __builtin_abort ();
+  D c6 = f6 (B());
+  if (c6.i != 3)
+    __builtin_abort ();
+  D c7 = f7 (B());
+  if (c7.i != 4)
+    __builtin_abort ();
+  D c8 = f8 ();
+  if (c8.i != 3)
+    __builtin_abort ();
+  D c9 = f9 ();
+  if (c9.i != 4)
+    __builtin_abort ();
+  D c10 = f10 ();
+  if (c10.i != 4)
+    __builtin_abort ();
+}