This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] tree-ssa-dom.c: Fix memory leak.


Hi,

Attached is a patch to fix memory leak in record_edge_info.

In record_edge_info, we have a sequence of three "if" statements like
so.

  if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
      && TREE_CODE (op0) == SSA_NAME
      && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
      && is_gimple_min_invariant (op1))

  if (is_gimple_min_invariant (op0)
      && (TREE_CODE (op1) == SSA_NAME
	  || is_gimple_min_invariant (op1)))

  if (TREE_CODE (op0) == SSA_NAME
      && (is_gimple_min_invariant (op1)
	  || TREE_CODE (op1) == SSA_NAME))

Blocks under each of these "if" statements allocate edge_info for two
edges of a COND_EXPR.  The problem is that when the first "if"
condition holds, the third one necessarily holds, too.  In this case,
e->aux that is set in the first "if" block will be overwritten by the
third "if" statement.  We end up with a situation where nobody
references the edge_info data structure allocated in the first "if"
block.

The patch fixes the problem by putting "else" in the second and third
"if" statements so that at most one "if" will trigger.

With this patch, we no longer record expressions like LE_EXPR or
GE_EXPR for boolean equality, but that should be OK as I don't think
we use LE_EXPR or GE_EXPR on booleans.

Tested on i686-pc-linux-gnu.  OK to apply?

Kazu Hirata

2004-12-10  Kazu Hirata  <kazu@cs.umass.edu>

	* tree-ssa-dom.c (record_edge_info): Fix memory leak.

Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dom.c,v
retrieving revision 2.73
diff -c -d -p -r2.73 tree-ssa-dom.c
*** tree-ssa-dom.c	3 Dec 2004 07:38:39 -0000	2.73
--- tree-ssa-dom.c	10 Dec 2004 16:08:59 -0000
*************** record_edge_info (basic_block bb)
*** 2451,2459 ****
  		    }
  		}
  
! 	      if (is_gimple_min_invariant (op0)
! 		  && (TREE_CODE (op1) == SSA_NAME
! 		       || is_gimple_min_invariant (op1)))
  		{
  		  tree inverted = invert_truthvalue (cond);
  		  struct edge_info *edge_info;
--- 2451,2459 ----
  		    }
  		}
  
! 	      else if (is_gimple_min_invariant (op0)
! 		       && (TREE_CODE (op1) == SSA_NAME
! 			   || is_gimple_min_invariant (op1)))
  		{
  		  tree inverted = invert_truthvalue (cond);
  		  struct edge_info *edge_info;
*************** record_edge_info (basic_block bb)
*** 2477,2485 ****
  		    }
  		}
  
! 	      if (TREE_CODE (op0) == SSA_NAME
! 		  && (is_gimple_min_invariant (op1)
! 		      || TREE_CODE (op1) == SSA_NAME))
  		{
  		  tree inverted = invert_truthvalue (cond);
  		  struct edge_info *edge_info;
--- 2477,2485 ----
  		    }
  		}
  
! 	      else if (TREE_CODE (op0) == SSA_NAME
! 		       && (is_gimple_min_invariant (op1)
! 			   || TREE_CODE (op1) == SSA_NAME))
  		{
  		  tree inverted = invert_truthvalue (cond);
  		  struct edge_info *edge_info;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]