Fix pr45962 : fallout from stack alignment patch

Submitted by Richard Henderson on Oct. 11, 2010, 10:45 p.m.

Details

Message ID 4CB39374.8030107@redhat.com
State New
Headers show

Commit Message

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 hide | download patch | download mbox

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;