https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87095
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- With my very limited understanding of the inheritance and ABI, I think the testcase is valid. The problem is I believe in that if there are nearly empty virtual bases that the ABI requires to reuse the virtual pointers in that case: /* A "nearly-empty" virtual base class can be the primary base class, if no non-virtual polymorphic base can be found. Look for a nearly-empty virtual dynamic base that is not already a primary base of something in the hierarchy. If there is no such base, just pick the first nearly-empty virtual base. */ the build_clobber_this () handles this by: /* If we have virtual bases, clobber the whole object, but only if we're in charge. If we don't have virtual bases, clobber the as-base type so we don't mess with tail padding. */ bool vbases = CLASSTYPE_VBASECLASSES (current_class_type); ... if (vbases) exprstmt = build_if_in_charge (exprstmt); So, to match this it would be just adding if (CLASSTYPE_VBASECLASSES (current_class_type)) stmt = build_if_in_charge (stmt); before finish_decl_cleanup. Though, if all the virtual bases are non-empty, the sharing of vptr doesn't occur in that case and we'd not clear it (e.g. if in the testcase there is int a; non-static data member in A, we wouldn't clear B's vptr in not-in-charge B::~B even when A has a different vptr). So I wonder if the following is right: --- gcc/cp/decl.c.jj 2018-08-26 22:41:48.574350447 +0200 +++ gcc/cp/decl.c 2018-08-27 12:59:33.068314097 +0200 @@ -15696,6 +15696,14 @@ begin_destructor_body (void) tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR, vtbl, tf_warning_or_error); + /* If the vptr is shared with some virtual nearly empty base, + don't clear it if not in charge, the dtor of the virtual + nearly empty base will do that later. */ + if (CLASSTYPE_VBASECLASSES (current_class_type) + && CLASSTYPE_PRIMARY_BINFO (current_class_type) + && BINFO_VIRTUAL_P + (CLASSTYPE_PRIMARY_BINFO (current_class_type))) + stmt = build_if_in_charge (stmt); finish_decl_cleanup (NULL_TREE, stmt); } else