--- gcc/cp/decl2.c.jj 2009-11-18 15:48:50.000000000 +0100 +++ gcc/cp/decl2.c 2009-12-01 08:33:36.000000000 +0100 @@ -3449,6 +3449,16 @@ no_linkage_error (tree decl) "is used but never defined", decl, t); } +#ifdef ENABLE_CHECKING +static GTY(()) tree vdtor_pairs; +void add_vdtor_pair (tree, tree); +void +add_vdtor_pair (tree base_dtor, tree deleting_dtor) +{ + vdtor_pairs = tree_cons (base_dtor, deleting_dtor, vdtor_pairs); +} +#endif + /* This routine is called at the end of compilation. Its job is to create all the code needed to initialize and destroy the global aggregates. We do the destruction @@ -3823,6 +3833,9 @@ cp_write_global_declarations (void) #ifdef ENABLE_CHECKING validate_conversion_obstack (); + + for (; vdtor_pairs; vdtor_pairs = TREE_CHAIN (vdtor_pairs)) + gcc_assert (!(TREE_ASM_WRITTEN (TREE_VALUE (vdtor_pairs)) ^ TREE_ASM_WRITTEN (TREE_PURPOSE (vdtor_pairs)))); #endif /* ENABLE_CHECKING */ } --- gcc/cp/optimize.c.jj 2009-12-01 10:32:13.000000000 +0100 +++ gcc/cp/optimize.c 2009-12-01 00:02:09.000000000 +0100 @@ -388,9 +388,15 @@ maybe_clone_body (tree fn) { DECL_COMDAT_GROUP (fns[1]) = comdat_group; if (fns[2]) - /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is - virtual, it goes into the same comdat group as well. */ - DECL_COMDAT_GROUP (fns[2]) = comdat_group; + { +#ifdef ENABLE_CHECKING +extern void add_vdtor_pair (tree base_dtor, tree deleting_dtor); +add_vdtor_pair (fns[0], fns[2]); +#endif + /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is + virtual, it goes into the same comdat group as well. */ + DECL_COMDAT_GROUP (fns[2]) = comdat_group; + } } /* We don't need to process the original function any further. */