This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Fix PR2207
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH: Fix PR2207
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Sun, 15 Apr 2001 19:51:34 -0700
- Organization: CodeSourcery, LLC
This patch fixes a regression from GCC 2.95.x as evidenced by the
attached test-case.
Tested on i686-pc-linux-gnu.
Installed on the mainline and on the branch.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2001-04-15 Mark Mitchell <mark@codesourcery.com>
* init.c (build_delete): Create a SAVE_EXPR for the address if
we're going to use it more than once.
Index: testsuite/g++.old-deja/g++.other/delete8.C
===================================================================
RCS file: delete8.C
diff -N delete8.C
*** /dev/null Tue May 5 13:32:27 1998
--- delete8.C Sun Apr 15 19:36:18 2001
***************
*** 0 ****
--- 1,39 ----
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+
+ #include <stdlib.h>
+
+ struct S {
+ ~S ();
+ };
+
+ bool flag;
+ S* s1;
+ S* s2;
+
+ void* operator new (size_t s)
+ {
+ return malloc (s);
+ }
+
+ void operator delete (void* p)
+ {
+ if (flag && p != s2)
+ abort ();
+ }
+
+ S::~S () {
+ if (this != s2)
+ abort ();
+ s1 = 0;
+ }
+
+ int main () {
+ s2 = new S;
+ s1 = s2;
+ // Turn on the check in `operator delete'.
+ flag = true;
+ delete s1;
+ // Turn it off again so that normal shutdown code works.
+ flag = false;
+ }
+
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.232.2.7
diff -c -p -r1.232.2.7 init.c
*** init.c 2001/03/20 22:03:45 1.232.2.7
--- init.c 2001/04/16 02:36:18
*************** build_delete (type, addr, auto_delete, f
*** 3155,3161 ****
{
tree member;
tree expr;
- tree ref;
if (addr == error_mark_node)
return error_mark_node;
--- 3155,3160 ----
*************** build_delete (type, addr, auto_delete, f
*** 3184,3190 ****
/* throw away const and volatile on target type of addr */
addr = convert_force (build_pointer_type (type), addr, 0);
- ref = build_indirect_ref (addr, NULL_PTR);
}
else if (TREE_CODE (type) == ARRAY_TYPE)
{
--- 3183,3188 ----
*************** build_delete (type, addr, auto_delete, f
*** 3209,3216 ****
addr = save_expr (addr);
addr = convert_force (build_pointer_type (type), addr, 0);
-
- ref = build_indirect_ref (addr, NULL_PTR);
}
my_friendly_assert (IS_AGGR_TYPE (type), 220);
--- 3207,3212 ----
*************** build_delete (type, addr, auto_delete, f
*** 3239,3244 ****
--- 3235,3242 ----
delete'. */
if (use_global_delete && auto_delete == sfk_deleting_destructor)
{
+ /* We will use ADDR multiple times so we must save it. */
+ addr = save_expr (addr);
/* Delete the object. */
do_delete = build_builtin_delete_call (addr);
/* Otherwise, treat this like a complete object destructor
*************** build_delete (type, addr, auto_delete, f
*** 3251,3257 ****
else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTORS (type))
&& auto_delete == sfk_deleting_destructor)
{
! /* Buidl the call. */
do_delete = build_op_delete_call (DELETE_EXPR,
addr,
c_sizeof_nowarn (type),
--- 3249,3257 ----
else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTORS (type))
&& auto_delete == sfk_deleting_destructor)
{
! /* We will use ADDR multiple times so we must save it. */
! addr = save_expr (addr);
! /* Build the call. */
do_delete = build_op_delete_call (DELETE_EXPR,
addr,
c_sizeof_nowarn (type),
*************** build_delete (type, addr, auto_delete, f
*** 3261,3267 ****
auto_delete = sfk_complete_destructor;
}
! expr = build_dtor_call (ref, auto_delete, flags);
if (do_delete)
expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
--- 3261,3268 ----
auto_delete = sfk_complete_destructor;
}
! expr = build_dtor_call (build_indirect_ref (addr, NULL_PTR),
! auto_delete, flags);
if (do_delete)
expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
*************** build_delete (type, addr, auto_delete, f
*** 3285,3290 ****
--- 3286,3292 ----
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (type);
tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE;
tree exprstmt = NULL_TREE;
+ tree ref = build_indirect_ref (addr, NULL_PTR);
/* Set this again before we call anything, as we might get called
recursively. */