Here we were crashing because while the class C has a destructor, it hasn't yet been declared at this point in maybe_emit_vtables, so CLASSTYPE_DESTRUCTOR is null, so checking DECL_DEFAULTED_IN_CLASS_P crashed. Fixed by checking CLASSTYPE_LAZY_DESTRUCTOR first.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-01-13 Marek Polacek <pola...@redhat.com> PR c++/88830 - ICE with abstract class. * decl2.c (maybe_emit_vtables): Check CLASSTYPE_LAZY_DESTRUCTOR. Fix formatting. * g++.dg/other/abstract7.C: New test. diff --git gcc/cp/decl2.c gcc/cp/decl2.c index e4cf4e0a361..7b656712471 100644 --- gcc/cp/decl2.c +++ gcc/cp/decl2.c @@ -2229,7 +2229,8 @@ maybe_emit_vtables (tree ctype) never get generated. */ if (CLASSTYPE_PURE_VIRTUALS (ctype) && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) - && DECL_DEFAULTED_IN_CLASS_P(CLASSTYPE_DESTRUCTOR(ctype))) + && !CLASSTYPE_LAZY_DESTRUCTOR (ctype) + && DECL_DEFAULTED_IN_CLASS_P (CLASSTYPE_DESTRUCTOR (ctype))) note_vague_linkage_fn (CLASSTYPE_DESTRUCTOR(ctype)); /* Since we're writing out the vtable here, also write the debug diff --git gcc/testsuite/g++.dg/other/abstract7.C gcc/testsuite/g++.dg/other/abstract7.C new file mode 100644 index 00000000000..95781602c95 --- /dev/null +++ gcc/testsuite/g++.dg/other/abstract7.C @@ -0,0 +1,14 @@ +// PR c++/88830 + +struct a { + ~a(); +}; +class b { + virtual void c(int &); +}; +class C : b { + void c(int &); + virtual int d() = 0; + a e; +}; +void C::c(int &) {}