https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69096
Bug ID: 69096
Summary: [concepts] return type deduction before checking
constraint satisfaction
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: Casey at Carter dot net
Target Milestone: ---
Created attachment 37196
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37196&action=edit
Test case
r231964 miscompiles this valid TU:
template <class R>
constexpr bool has_customization = false;
template <class R>
requires
requires(R&& r) { iter_move((R&&)r); }
constexpr bool has_customization<R> = true;
template <class C>
struct basic_iterator
{
C pos_;
// template <int=42>
friend decltype(auto) iter_move(const basic_iterator& i)
requires
requires { i.pos_.move(); }
{
return i.pos_.move();
}
};
static_assert(!has_customization<basic_iterator<int>>);
which it diagnoses with:
~/gcc6-r231964/bin/g++ -std=c++1z foo.cpp -c
foo.cpp: In instantiation of ‘decltype(auto) iter_move(const
basic_iterator<int>&)’:
foo.cpp:5:30: required from here
foo.cpp:18:19: error: request for member ‘move’ in
‘i.basic_iterator<int>::pos_’, which is of non-class type ‘const int’
return i.pos_.move();
~~~~~~~^~~~
The program compiles correctly - the iter_move definition properly does not
participate in overload resolution - if:
* the "template <int=42>" line is uncommented so that iter_move is a function
template, or
* the return type is declared as int or void, presumably anything that doesn't
require return type deduction.
I speculate that the compiler is performing return type deduction *before*
checking for satisfaction of the associated constraints.