diff mbox

Make assert in gimple_phi_arg more strict

Message ID da4d40fe-6842-4e71-bc62-8f96c0f5efaf@mentor.com
State New
Headers show

Commit Message

Tom de Vries July 20, 2017, 8:39 a.m. UTC
Hi,

this patch checks that gimple_phi_arg accesses args only in the 
inclusive 0..(nargs-1) region.

There are a couple of functions that manipulate args in the inclusive 
nargs..(capacity-1) region, so these have been updated to temporarily 
increase nargs to capacity while doing the manipulation.

Using this patch, I found PR81489 - "invalid phi argument used in 
find_implicit_erroneous_behavior".

Bootstrapped and reg-tested on x86_64.

OK for trunk?

Thanks,
- Tom
diff mbox

Patch

Make assert in gimple_phi_arg more strict

2017-07-20  Tom de Vries  <tom@codesourcery.com>

	* gimple.h (gimple_phi_arg): Make assert more strict.
	* tree-phinodes.c (make_phi_node, resize_phi_node): Set nargs
	temporarily to capacity, to be able to access the entire args array.
	(reserve_phi_args_for_new_edge): Increase nargs earlier.

---
 gcc/gimple.h        |  2 +-
 gcc/tree-phinodes.c | 15 ++++++++++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/gcc/gimple.h b/gcc/gimple.h
index aba7167..262a702 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -4341,7 +4341,7 @@  static inline struct phi_arg_d *
 gimple_phi_arg (gimple *gs, unsigned index)
 {
   gphi *phi_stmt = as_a <gphi *> (gs);
-  gcc_gimple_checking_assert (index < phi_stmt->capacity);
+  gcc_gimple_checking_assert (index < phi_stmt->nargs);
   return &(phi_stmt->args[index]);
 }
 
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
index c49c5c1..daa5d43 100644
--- a/gcc/tree-phinodes.c
+++ b/gcc/tree-phinodes.c
@@ -190,6 +190,10 @@  make_phi_node (tree var, int len)
   else
     gimple_phi_set_result (phi, make_ssa_name (var, phi));
 
+  /* Temporarily set nargs to capacity, to be able to initialize the entire args
+     array.  */
+  unsigned nargs = phi->nargs;
+  phi->nargs = phi->capacity;
   for (i = 0; i < capacity; i++)
     {
       use_operand_p  imm;
@@ -201,6 +205,7 @@  make_phi_node (tree var, int len)
       imm->next = NULL;
       imm->loc.stmt = phi;
     }
+  phi->nargs = nargs;
 
   return phi;
 }
@@ -260,7 +265,11 @@  resize_phi_node (gphi *phi, size_t len)
 
   new_phi->capacity = len;
 
-  for (i = gimple_phi_num_args (new_phi); i < len; i++)
+  unsigned nargs = gimple_phi_num_args (new_phi);
+  /* Temporarily set nargs to capacity, to be able to initialize the entire args
+     array.  */
+  new_phi->nargs = new_phi->capacity;
+  for (i = nargs; i < len; i++)
     {
       use_operand_p imm;
 
@@ -271,6 +280,7 @@  resize_phi_node (gphi *phi, size_t len)
       imm->next = NULL;
       imm->loc.stmt = new_phi;
     }
+  new_phi->nargs = nargs;
 
   return new_phi;
 }
@@ -307,10 +317,9 @@  reserve_phi_args_for_new_edge (basic_block bb)
 	 example, the loop optimizer duplicates several basic blocks,
 	 redirects edges, and then fixes up PHI arguments later in
 	 batch.  */
+      stmt->nargs++;
       SET_PHI_ARG_DEF (stmt, len - 1, NULL_TREE);
       gimple_phi_arg_set_location (stmt, len - 1, UNKNOWN_LOCATION);
-
-      stmt->nargs++;
     }
 }