| Issue |
185024
|
| Summary |
[clang-tidy] modernize-use-ranges activates for types with operator<=> but not operator==
|
| Labels |
clang-tidy
|
| Assignees |
|
| Reporter |
Alcaro
|
```
$ cat a.cpp
#include <algorithm>
#include <vector>
struct foo {
int a;
auto operator<=>(const foo& other) const {
return a <=> other.a;
}
};
int main() {
std::vector<foo> v;
std::sort(v.begin(), v.end());
}
$ clang++ -std=c++23 a.cpp
$ clang-tidy *.cpp --checks=modernize-use-ranges --extra-arg=-std=c++23 --fix
[...]
a.cpp:13:5: warning: use a ranges version of this algorithm [modernize-use-ranges]
[...]
clang-tidy applied 3 of 3 suggested fixes.
$ cat a.cpp
#include <algorithm>
#include <vector>
struct foo {
int a;
auto operator<=>(const foo& other) const {
return a <=> other.a;
}
};
int main() {
std::vector<foo> v;
std::ranges::sort(v);
}
$ clang++ -std=c++23 a.cpp
a.cpp:13:5: error: no matching function for call to object of type 'const __sort_fn'
[...]
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:360:25: note: because 'is_invocable_v<std::ranges::less &, foo &, foo &>' evaluated to false
[...]
1 error generated.
```
<details>
<summary>full compiler error</summary>
```
$ clang++ -std=c++23 a.cpp
a.cpp:13:5: error: no matching function for call to object of type 'const __sort_fn'
13 | std::ranges::sort(v);
| ^~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/ranges_algo.h:1802:7: note: candidate template ignored: constraints not satisfied [with _Range = std::vector<foo> &, _Comp = ranges::less, _Proj = identity]
1802 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/ranges_algo.h:1800:16: note: because 'sortable<iterator_t<vector<foo, allocator<foo> > &>, std::ranges::less, std::identity>' evaluated to false
1800 | requires sortable<iterator_t<_Range>, _Comp, _Proj>
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/iterator_concepts.h:974:10: note: because 'indirect_strict_weak_order<std::ranges::less, projected<__normal_iterator<foo *, vector<foo, allocator<foo> > >, identity> >' evaluated to false
974 | && indirect_strict_weak_order<_Rel, projected<_Iter, _Proj>>;
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/iterator_concepts.h:768:10: note: because 'strict_weak_order<std::ranges::less &, __indirect_value_t<__type>, __indirect_value_t<__type> >' evaluated to false
768 | && strict_weak_order<_Fn&, __indirect_value_t<_I1>, __indirect_value_t<_I2>>
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:383:33: note: because 'relation<std::ranges::less &, foo &, foo &>' evaluated to false
383 | concept strict_weak_order = relation<_Rel, _Tp, _Up>;
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:374:9: note: because 'predicate<std::ranges::less &, foo &, foo &>' evaluated to false
374 | = predicate<_Rel, _Tp, _Tp> && predicate<_Rel, _Up, _Up>
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:368:25: note: because 'regular_invocable<std::ranges::less &, foo &, foo &>' evaluated to false
368 | concept predicate = regular_invocable<_Fn, _Args...>
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:364:33: note: because 'invocable<std::ranges::less &, foo &, foo &>' evaluated to false
364 | concept regular_invocable = invocable<_Fn, _Args...>;
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/concepts:360:25: note: because 'is_invocable_v<std::ranges::less &, foo &, foo &>' evaluated to false
360 | concept invocable = is_invocable_v<_Fn, _Args...>;
| ^
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/ranges_algo.h:1789:7: note: candidate function template not viable: requires at least 2 arguments, but 1 was provided
1789 | operator()(_Iter __first, _Sent __last,
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1790 | _Comp __comp = {}, _Proj __proj = {}) const
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
```
</details>
Expected: Either don't change working code to non-working code, or print a loud warning that user-provided operator<=> without operator== is a footgun.
(One could also argue that the wall of text error is a bug.)
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs