aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <mpolacek@gcc.gnu.org>2018-09-05 21:17:47 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2018-09-05 21:17:47 +0000
commit62c21ceea64291317650258921c34dea79b1e96b (patch)
treefd16f085a85e12e1a1f4de48c05682914012a593 /gcc
parentf6b95f78f8048e2fe726b6caf91d606f36f4d8c4 (diff)
downloadgcc-62c21ceea64291317650258921c34dea79b1e96b.zip
gcc-62c21ceea64291317650258921c34dea79b1e96b.tar.gz
gcc-62c21ceea64291317650258921c34dea79b1e96b.tar.bz2
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. * g++.dg/cpp0x/ref-qual19.C: New test. From-SVN: r264132
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/ref-qual19.C117
4 files changed, 137 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 498b1fa..b4ec9f4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index a156702..942b2c2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6936dd5..a736ccf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..8494b83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual19.C
@@ -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 ();
+}