https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521
Bug ID: 86521
Summary: GCC 8 selects incorrect overload of ref-qualified
conversion operator template
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: yannick.lepennec+gcc at live dot fr
Target Milestone: ---
Please consider the following code, built with `g++ -std=c++17 -Wall -Wextra
-pedantic`.
It used to be accepted by GCC 7.3, but this is no longer the case since GCC 8.
Godbolt for convenience: https://godbolt.org/g/oXFQex
It was broken since r258755, which makes this code ICE instead. The ICE itself
was fixed in r259123, but said fix now makes GCC reject it with the below
error.
This is still the case on today's r262658. As far as I can tell, GCC seems to
be incorrectly selecting the `const&` overload instead of the `&&` one.
#include <utility>
template<typename T>
struct require_cast {
T val;
template<typename U>
explicit operator U () && {
return std::move(val);
}
template<typename U>
explicit operator U const& () const& {
return val;
}
};
struct base {
base() = default;
base(base&&) = default;
base& operator=(base&&) = default;
base(base const&) = delete;
base& operator=(base const&) = delete;
};
struct derived : base {};
int main() {
require_cast<derived> d;
(void)static_cast<base>(std::move(d));
(void)static_cast<derived>(std::move(d));
}
repro.c++: In function ‘int main()’:
repro.c++:34:41: error: use of deleted function ‘base::base(const base&)’
(void)static_cast<base>(std::move(d));
^
repro.c++:23:5: note: declared here
base(base const&) = delete;
^~~~
repro.c++:35:44: error: use of deleted function ‘derived::derived(const
derived&)’
(void)static_cast<derived>(std::move(d));
^
repro.c++:27:8: note: ‘derived::derived(const derived&)’ is implicitly deleted
because the default definition would be ill-formed:
struct derived : base {};
^~~~~~~
repro.c++:27:8: error: use of deleted function ‘base::base(const base&)’
repro.c++:23:5: note: declared here
base(base const&) = delete;
^~~~