From: Jason Merrill Date: Thu, 13 Sep 2007 13:42:11 +0000 (-0400) Subject: re PR c++/15097 (code generator problem with ::delete and multiple inheritance and... X-Git-Tag: releases/gcc-4.2.2~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21f643029a4d6123581664c3c95800380c19084c;p=thirdparty%2Fgcc.git re PR c++/15097 (code generator problem with ::delete and multiple inheritance and virtual deconstructs) PR c++/15097 * init.c (build_delete): Use build_headof to get the address of the complete object if we aren't using the deleting destructor. * rtti.c (build_headof): No longer static. * cp-tree.h: Declare it. From-SVN: r128464 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e975e4b17927..6a1d20d87281 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2007-09-13 Jason Merrill + + PR c++/15097 + * init.c (build_delete): Use build_headof to get the address of the + complete object if we aren't using the deleting destructor. + * rtti.c (build_headof): No longer static. + * cp-tree.h: Declare it. + 2007-09-11 Jason Merrill PR c++/31419 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f35a19a7ad6a..48d8de8ff202 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4178,6 +4178,7 @@ extern void init_rtti_processing (void); extern tree build_typeid (tree); extern tree get_tinfo_decl (tree); extern tree get_typeid (tree); +extern tree build_headof (tree); extern tree build_dynamic_cast (tree, tree); extern void emit_support_tinfos (void); extern bool emit_tinfo_decl (tree); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 8125f189f856..3c570c842f37 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2788,6 +2788,7 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, } else { + tree head = NULL_TREE; tree do_delete = NULL_TREE; tree ifexp; @@ -2801,8 +2802,9 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, { /* We will use ADDR multiple times so we must save it. */ addr = save_expr (addr); + head = get_target_expr (build_headof (addr)); /* Delete the object. */ - do_delete = build_builtin_delete_call (addr); + do_delete = build_builtin_delete_call (head); /* Otherwise, treat this like a complete object destructor call. */ auto_delete = sfk_complete_destructor; @@ -2841,6 +2843,10 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, if (do_delete) expr = build2 (COMPOUND_EXPR, void_type_node, expr, do_delete); + /* We need to calculate this before the dtor changes the vptr. */ + if (head) + expr = build2 (COMPOUND_EXPR, void_type_node, head, expr); + if (flags & LOOKUP_DESTRUCTOR) /* Explicit destructor call; don't check for null pointer. */ ifexp = integer_one_node; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 9605479e8265..dcf4e72ad7e6 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -100,7 +100,6 @@ VEC(tree,gc) *unemitted_tinfo_decls; and are generated as needed. */ static GTY (()) VEC(tinfo_s,gc) *tinfo_descs; -static tree build_headof (tree); static tree ifnonnull (tree, tree); static tree tinfo_name (tree); static tree build_dynamic_cast_1 (tree, tree); @@ -154,7 +153,7 @@ init_rtti_processing (void) virtual functions (TYPE_POLYMORPHIC_P), else just return the expression. */ -static tree +tree build_headof (tree exp) { tree type = TREE_TYPE (exp);