https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128097
Bug ID: 128097
Summary: ICE in record_target_from_binfo at ipa-devirt.cc:2641
with -O2
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: ice-on-valid-code
Severity: normal
Priority: P3
Component: ipa
Assignee: unassigned at gcc dot gnu.org
Reporter: yqtian668 at gmail dot com
Target Milestone: ---
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build: x86_64-pc-linux-gnu
g++ -O2 aborts during speculative devirtualization while compiling virtual
calls in the destructor of a class with a virtual base.
Testcase:
struct C1 {
unsigned x3 = 1;
virtual unsigned f2() { return x3; }
};
struct C2 : C1 {
unsigned x5 = 2;
};
unsigned g(C1& r);
struct C3 : virtual C2 {
unsigned x6 = 3;
~C3() {
g(*this);
static_cast<C2&>(*this).f2();
}
unsigned f2() override { return x5; }
};
struct C4 : C3 {
unsigned x7 = 4;
unsigned x8 = 5;
unsigned f2() override { return x6; }
};
unsigned g(C1& r) { return r.f2(); }
int main() { C3 o2[2]; }
Command:
g++ -std=c++17 -O2 testcase.cpp
Actual behavior: GCC aborts during the IPA inline pass with "internal compiler
error: in record_target_from_binfo, at ipa-devirt.cc:2641". The stack contains
try_speculative_devirtualization, ipa_get_indirect_edge_target_1, and
estimate_edge_devirt_benefit.
Expected behavior: GCC should compile the valid C++ program without an internal
compiler error. A destructor may make virtual calls on *this; during C3::~C3,
the dynamic type used for virtual dispatch is C3.
-O1, -O2 -fno-devirtualize-speculatively, and -O2 -fno-inline compile
successfully. Clang also compiles the testcase successfully.
Compiler version:
g++ (GCC) 17.0.0 20261021 (experimental)
GCC revision 8cc6e7178c2e3b6156d7992bd18285be0da3c92c
Target: x86_64-pc-linux-gnu
The failing source location follows get_binfo_at_offset(...) returning null.
The assertion then assumes that an ODR violation was already reported. In this
testcase, the speculative context is formed while the destructor is inlined
into the array destruction path, and the virtual C2 base has a different offset
in the more-derived C4 layout.