@@ -14354,7 +14354,9 @@ begin_destructor_body (void)
initialize_vtbl_ptrs (current_class_ptr);
finish_compound_stmt (compound_stmt);
- if (flag_lifetime_dse)
+ if (flag_lifetime_dse
+ /* Clobbering an empty base is harmful if it overlays real data. */
+ && !is_empty_class (current_class_type))
{
/* Insert a cleanup to let the back end know that the object is dead
when we exit the destructor, either normally or via exception. */
@@ -10,4 +10,4 @@ int main() {
C c;
if ( c.a == false )
__builtin_abort();
-};
+}
@@ -0,0 +1,11 @@
+// PR c++/70272
+// { dg-options -O2 }
+// { dg-do run }
+
+struct Empty { };
+struct A { A() : a(true) { } bool a; ~A() { if (!a) __builtin_abort(); } };
+struct B : Empty { B() : Empty() { } ~B() { } };
+struct C : A, B { C() : A(), B() { } ~C() { } };
+int main() {
+ C c;
+}
@@ -26,5 +26,5 @@ t (void)
// { dg-final { scan-tree-dump-times "Empty EH handler" 2 "ehcleanup1" } }
//
// And as a result also contained control flow.
-// { dg-final { scan-tree-dump-times "Removing unreachable" 6 "ehcleanup1" } }
+// { dg-final { scan-tree-dump-times "Removing unreachable" 4 "ehcleanup1" } }
//