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

Reply via email to