C++ PATCH: Fix PR2207

Mark Mitchell mark@codesourcery.com
Sun Apr 15 19:51:00 GMT 2001


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.  */



More information about the Gcc-patches mailing list