https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88114

Tobias Burnus <burnus at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #1 from Tobias Burnus <burnus at gcc dot gnu.org> ---
The reason that the presence of a single
  virtual ... = 0;
will remove the 'virtual ~One() = default' seems to be the following code in
cp/class.c's build_vtbl_initializer (added in r208845 in 2014):

              /* Don't refer to a virtual destructor from a constructor
                 vtable or a vtable for an abstract class, since destroying
                 an object under construction is undefined behavior and we
                 don't want it to be considered a candidate for speculative
                 devirtualization.  But do create the thunk for ABI
                 compliance.  */
              if (DECL_DESTRUCTOR_P (fn_original)
                  && (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original))
                      || orig_binfo != binfo))
                init = size_zero_node;

That affects the code generation via cp/decl2.c's maybe_emit_vtables() which
calls mark_needed() for all non-size_zero_node items.

In principle, that's also called for
  inline virtual ~One() {}
such that the vtable seems to contain a NULL -- but the destructor function
itself is emitted. My feeling is that something marks the tree as needed and,
hence, the symbol is produced.  [Probably via somehow via parser.c's
cp_parser_save_member_function_body().]


Finally, the reason that the One::~One() works without "#pragma interface" is
not that it is generated when compiling "test.cc" but it will be generated when
compiling "test3.cc".

Reply via email to