* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128172
138bc75d-0d04-0410-961f-
82ee72b054a4
+2007-09-05 Jason Merrill <jason@redhat.com>
+
+ 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-06 Jakub Jelinek <jakub@redhat.com>
* decl.c (duplicate_decls): Set TREE_NOTHROW on __builtin_XX
2007-09-04 Jason Merrill <jason@redhat.com>
+ * except.c (initialize_handler_parm): Use
+ fold_build_cleanup_point_expr.
+
PR c++/31419
* call.c (reference_binding): Don't look for user-defined conversions
to the same type.
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);
}
else
{
+ tree head = NULL_TREE;
tree do_delete = NULL_TREE;
tree ifexp;
{
/* 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;
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;
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);
virtual functions (TYPE_POLYMORPHIC_P), else just return the
expression. */
-static tree
+tree
build_headof (tree exp)
{
tree type = TREE_TYPE (exp);
--- /dev/null
+// PR c++/15097
+// { dg-do run }
+
+typedef __SIZE_TYPE__ size_t;
+
+extern "C" void * malloc (size_t);
+extern "C" void free (void *);
+extern "C" void abort(void);
+
+void *saved;
+
+void * operator new (size_t size)
+{
+ void *p = malloc (size);
+ saved = p;
+ return p;
+}
+
+void operator delete (void *p)
+{
+ if (p != saved)
+ abort ();
+ free (p);
+}
+
+struct B1
+{
+ virtual ~B1 () throw() {}
+ B1 (){}
+ int x;
+};
+struct B2
+{
+ virtual ~B2 () throw() {}
+ B2 (){}
+ int x;
+};
+struct D : B1, B2
+{
+ D (){}
+ ~D () throw() {}
+ int y;
+};
+void f1 (D*);
+void f2 (B2*);
+void f3 (B1*);
+int main (void)
+{
+ f1 (::new D);
+ f2 (::new D);
+ f3 (::new D);
+}
+void f1 ( D* p) { ::delete p; }
+void f2 (B2* p) { ::delete p; }
+void f3 (B1* p) { ::delete p; }