https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119203
Bug ID: 119203
Summary: A type with a constrained operator-> gives error: base
operand of '->' has non-pointer type
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Keywords: diagnostic
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
template<typename T>
struct Iter
{
T t;
auto operator->() const requires(t.operator->()) { return t.operator->(); }
};
struct S { int i; };
int main()
{
Iter<S> iter;
iter->i;
}
When compiled with -std=c++20 this invalid code gives:
arrow.cc: In function 'int main()':
arrow.cc:14:7: error: base operand of '->' has non-pointer type 'Iter<S>'
14 | iter->i;
| ^~
The code is invalid, but it would be better if the error said that the
operator->() could not be used because its constraints were not satisfied, as
any other member function would do.
For example, a constrained operator* gives a good error:
template<typename T>
struct Iter
{
T t;
int operator*() requires(*t) { return 1; }
};
struct S { int i; };
int main()
{
Iter<S> iter;
*iter;
}
arrow.cc: In function 'int main()':
arrow.cc:14:3: error: no match for 'operator*' (operand type is 'Iter<S>')
14 | *iter;
| ^~~~~
arrow.cc:14:3: note: there is 1 candidate
arrow.cc:6:7: note: candidate 1: 'int Iter<T>::operator*() requires
*((Iter<T>*)this)->Iter<T>::t [with T = S]'
6 | int operator*() requires(*t) { return 1; }
| ^~~~~~~~
arrow.cc:6:7: note: constraints not satisfied
arrow.cc: In instantiation of 'int Iter<T>::operator*() requires
*((Iter<T>*)this)->Iter<T>::t [with T = S]':
arrow.cc:14:4: required from here
14 | *iter;
| ^~~~
arrow.cc:6:7: required by the constraints of 'template<class T> int
Iter<T>::operator*() requires *((Iter<T>*)this)->Iter<T>::t'
arrow.cc:6:28: error: no match for 'operator*' (operand type is 'S')
6 | int operator*() requires(*t) { return 1; }
| ~^~~
This says there is no operator* for Iter<S> because its constraints were not
satisfied, and tells us that's because *t isn't valid.