https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94141
Bug ID: 94141 Summary: c++20 rewritten operator== recursive call mixing friend and external operators for template class Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: glisse at gcc dot gnu.org Target Milestone: --- (reduced from a user of boost/operators.hpp) template <typename> class A; template <typename T> bool operator==(const A<T>&, int) { return false; } template <typename> class A { friend bool operator==(int y, const A& x) { return x == y; } }; int main(){ A<short> q; q==3; 3==q; } $ g++ -std=c++2a a.c -Wall && ./a.out a.c: In instantiation of 'bool operator==(int, const A<short int>&)': a.c:10:6: required from here a.c:5:56: warning: in C++20 this comparison calls the current function recursively with reversed arguments 5 | friend bool operator==(int y, const A& x) { return x == y; } | ~~^~~~ zsh: segmentation fault ./a.out If I make both operators friends, or move both outside, gcc is happy, but in this mixed case, it doesn't seem to want to use the first operator== and prefers the rewritten second operator==. Of course removing the second operator== completely also works. Clang is fine with this version of the code. I have trouble parsing the standard wording, but IIRC one of the principles when adding <=> was that explicitly written functions should have priority over new, invented ones. Bug 93807 is the closest I could find.