Patchwork Fix pr45962 : fallout from stack alignment patch

login
register
mail settings
Submitter Richard Henderson
Date Oct. 11, 2010, 10:45 p.m.
Message ID <4CB39374.8030107@redhat.com>
Download mbox | patch
Permalink /patch/67490/
State New
Headers show

Comments

Richard Henderson - Oct. 11, 2010, 10:45 p.m.
If a variable has zero size, we should allocate at least one
byte for it, so that two variables of zero size have different
addresses.

This caught up with us here, when we had 1 variable of zero
size and failed to allocate any memory at all, leading to an
ICE dereferencing null.


r~
PR middle-end/45962
	* cfgexpand.c (add_stack_var): Ensure every variable has 1 byte.
	(expand_stack_vars): Assert large base allocated when used.

Patch

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index de686b5..1ef1fa0 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -253,6 +253,8 @@  alloc_stack_frame_space (HOST_WIDE_INT size, unsigned HOST_WIDE_INT align)
 static void
 add_stack_var (tree decl)
 {
+  struct stack_var *v;
+
   if (stack_vars_num >= stack_vars_alloc)
     {
       if (stack_vars_alloc)
@@ -262,17 +264,23 @@  add_stack_var (tree decl)
       stack_vars
 	= XRESIZEVEC (struct stack_var, stack_vars, stack_vars_alloc);
     }
-  stack_vars[stack_vars_num].decl = decl;
-  stack_vars[stack_vars_num].offset = 0;
-  stack_vars[stack_vars_num].size = tree_low_cst (DECL_SIZE_UNIT (SSAVAR (decl)), 1);
-  stack_vars[stack_vars_num].alignb = get_decl_align_unit (SSAVAR (decl));
+  v = &stack_vars[stack_vars_num];
+
+  v->decl = decl;
+  v->offset = 0;
+  v->size = tree_low_cst (DECL_SIZE_UNIT (SSAVAR (decl)), 1);
+  /* Ensure that all variables have size, so that &a != &b for any two
+     variables that are simultaneously live.  */
+  if (v->size == 0)
+    v->size = 1;
+  v->alignb = get_decl_align_unit (SSAVAR (decl));
 
   /* All variables are initially in their own partition.  */
-  stack_vars[stack_vars_num].representative = stack_vars_num;
-  stack_vars[stack_vars_num].next = EOC;
+  v->representative = stack_vars_num;
+  v->next = EOC;
 
   /* All variables initially conflict with no other.  */
-  stack_vars[stack_vars_num].conflicts = NULL;
+  v->conflicts = NULL;
 
   /* Ensure that this decl doesn't get put onto the list twice.  */
   set_rtl (decl, pc_rtx);
@@ -839,6 +847,7 @@  expand_stack_vars (bool (*pred) (tree))
 	  /* Large alignment is only processed in the last pass.  */
 	  if (pred)
 	    continue;
+	  gcc_assert (large_base != NULL);
 
 	  large_alloc += alignb - 1;
 	  large_alloc &= -(HOST_WIDE_INT)alignb;