[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-13 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

--- Comment #8 from Jason Merrill  ---
Author: jason
Date: Wed Mar 13 23:34:51 2019
New Revision: 269667

URL: https://gcc.gnu.org/viewcvs?rev=269667=gcc=rev
Log:
PR c++/86521 - C++17 copy elision in initialization by constructor.

This is an overlooked case in C++17 mandatory copy elision: We want overload
resolution to reflect that initializing an object from a prvalue does not
involve a copy or move constructor even when [over.match.ctor] says that
only constructors are candidates.  Here I implement that by looking through
the copy/move constructor in joust.

* call.c (joust_maybe_elide_copy): New.
(joust): Call it.

Modified:
trunk/gcc/cp/ChangeLog
trunk/gcc/cp/call.c
trunk/gcc/testsuite/g++.dg/cpp0x/overload-conv-3.C
trunk/gcc/testsuite/g++.dg/overload/conv-op2.C

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-12 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

--- Comment #7 from Jason Merrill  ---
Created attachment 45952
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45952=edit
patch to prefer copy elision

This implements that, but I'm going to hold off a bit before committing it.

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-11 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

--- Comment #6 from Jason Merrill  ---
(In reply to Jason Merrill from comment #4)
> The cast is ambiguous
> 
> To construct a 'base', we consider the two constructors
> 
> 1) base(const base&);
> 2) base(base&&);
> 
> for each of them we could convert the argument by either
> 
> 3) operator U () &&
> 4) operator U const& () const&
> 
> For #1 we want to convert to const base&.  For direct reference binding, #4
> is the only candidate, and it is viable.  For #2 we want to convert to
> base&&, only #3 is a candidate for direct reference binding, and it is
> viable.
> 
> The two user-defined conversion sequences are not comparable because they
> use different conversion operators, so the initialization is ambiguous.

...although perhaps the C++17 mandatory copy elision should alter this
calculation: initializing the object from the result of #3 doesn't actually use
the copy constructor.  In that case, we'd just be using #3, making it better
than #4+#2.  The standard doesn't currently say this, but it probably should.

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-11 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

--- Comment #5 from Jason Merrill  ---
Author: jason
Date: Tue Mar 12 03:19:22 2019
New Revision: 269602

URL: https://gcc.gnu.org/viewcvs?rev=269602=gcc=rev
Log:
PR c++/86521 - wrong overload resolution with ref-qualifiers.

Here we were wrongly treating binding a const lvalue ref to an xvalue as
direct binding, which is wrong under [dcl.init.ref] and [over.match.ref].

* call.c (build_user_type_conversion_1): Don't use a conversion to a
reference of the wrong rvalueness for direct binding.

Added:
trunk/gcc/testsuite/g++.dg/cpp0x/overload-conv-3.C
Modified:
trunk/gcc/cp/ChangeLog
trunk/gcc/cp/call.c
trunk/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-11 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

--- Comment #4 from Jason Merrill  ---
The cast is ambiguous

To construct a 'base', we consider the two constructors

1) base(const base&);
2) base(base&&);

for each of them we could convert the argument by either

3) operator U () &&
4) operator U const& () const&

For #1 we want to convert to const base&.  For direct reference binding, #4 is
the only candidate, and it is viable.  For #2 we want to convert to base&&,
only #3 is a candidate for direct reference binding, and it is viable.

The two user-defined conversion sequences are not comparable because they use
different conversion operators, so the initialization is ambiguous.

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-11 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

Jason Merrill  changed:

   What|Removed |Added

 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2019-03-11
   Assignee|unassigned at gcc dot gnu.org  |jason at gcc dot gnu.org
 Ever confirmed|0   |1

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-03-11 Thread matthijsvanduin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

Matthijs van Duin  changed:

   What|Removed |Added

 CC||matthijsvanduin at gmail dot 
com

--- Comment #3 from Matthijs van Duin  ---
First off, your example is more complicated than it needs to be. A more minimal
test case would be:

#include 

struct Dest {
Dest() = default;
Dest( Dest && ) = default;
Dest( Dest const & ) = delete;
};

struct Source {
Dest val;
operator Dest () && {
return std::move( val );
}
operator Dest const & () const & {
return val;
}
};

int main() {
Source x;
static_cast( std::move( x ) );
}


Second, notice that the two conversions are not really directly comparable
since one converts to directly Dest while the other converts to an expression
used to invoke a constructor of Dest. While it seems desirable for the former
to take preference over the latter, I'm not enough of a language lawyer to be
able to figure out what the C++ standard actually requires overload resolution
to do in this situation.

Replacing
operator Dest () && {
by
operator Dest && () && {
fixes the problem, and has the additional benefit of avoiding unnecessary
temporary materialization in situations like:

void foo( Dest && );
int main() {
Source x;
foo( std::move( x ) );
}

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2019-02-22 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|8.3 |8.4

--- Comment #2 from Jakub Jelinek  ---
GCC 8.3 has been released.

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2018-12-20 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P2

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2018-07-26 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|8.2 |8.3

--- Comment #1 from Jakub Jelinek  ---
GCC 8.2 has been released.

[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template

2018-07-16 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521

Richard Biener  changed:

   What|Removed |Added

   Keywords||rejects-valid
   Target Milestone|--- |8.2
Summary|GCC 8 selects incorrect |[8/9 Regression] GCC 8
   |overload of ref-qualified   |selects incorrect overload
   |conversion operator |of ref-qualified conversion
   |template|operator template