https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104603
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Last reconfirmed| |2022-03-01 CC| |msebor at gcc dot gnu.org --- Comment #8 from Martin Sebor <msebor at gcc dot gnu.org> --- It looks like the problem is that the call to Base::operator==() might enter infinite recursion. With the changed test case below GCC issues -Winfinite-recursion pointing it out. With the original test case the infinite recursion isn't inevitable but because it can't be ruled out GCC emits (invalid) code that then triggers -Warray-bounds. It might be possible to do better: detect the possible infinite recursion early and fold the equality to false. (As far as I can see, that's what recent Clang seems to do.) $ cat pr104603.C && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout pr104603.C struct Base { bool isX_; Base(bool isX = false) : isX_(isX) { } bool isX() const { return isX_; } bool operator==(const Base& rhs) const; }; struct X : public Base { X(const Base& b) : Base(true), b_(b) { } bool operator==(const X& rhs) const { return b_ == rhs.b_; } Base b_; }; inline bool Base::operator==(const Base& rhs) const { return /* isX() && rhs.isX() && */ static_cast<const X&>(*this) == static_cast<const X&>(rhs); } Base base (true); int main () { return X(base) == X(base); } pr104603.C: In member function ‘bool X::operator==(const X&) const’: pr104603.C:10:8: warning: infinite recursion detected [-Winfinite-recursion] 10 | bool operator==(const X& rhs) const { return b_ == rhs.b_; } | ^~~~~~~~ In member function ‘bool Base::operator==(const Base&) const’, inlined from ‘bool X::operator==(const X&) const’ at pr104603.C:10:51: pr104603.C:16:69: note: recursive call 16 | rn /* isX() && rhs.isX() && */ static_cast<const X&>(*this) == static_cast<const X&>(rhs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; Function main (main, funcdef_no=9, decl_uid=2452, cgraph_uid=10, symbol_order=10) (executed once) Merging blocks 3 and 4 int main () { <bb 2> [local count: 10631108]: <bb 3> [local count: 1073741824]: goto <bb 3>; [100.00%] }