From 62c21ceea64291317650258921c34dea79b1e96b Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 5 Sep 2018 21:17:47 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 9 +- gcc/cp/call.c | 8 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/cpp0x/ref-qual19.C | 117 ++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/ref-qual19.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 498b1fa9252..b4ec9f4b449 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 + + 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 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 a1567026975..942b2c204be 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 6936dd543f3..a736ccf999a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-09-05 Marek Polacek + + PR c++/87109, wrong overload with ref-qualifiers. + * g++.dg/cpp0x/ref-qual19.C: New test. + 2018-09-05 Bernhard Reutner-Fischer 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 00000000000..8494b83e5b0 --- /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 + +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 (); +} -- 2.30.2