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.

Reply via email to