Testing my patch to warn on overflow in calls to allocation
functions (bugs 77531 and 78284):

  https://gcc.gnu.org/ml/gcc-patches/2016-11/msg01672.html

exposed a number of instances of alloca(0) calls in GCC sources.
Besides this patch which enables the new warnings with -Wextra
(the patch is still in the review queue) the same code also
triggers a -Walloca-larger-than warning (which has to be
explicitly enabled).  It doesn't look to me like these calls
are bugs per se but in the interest of eating our own dog food
so to speak and being able to compile GCC with -Walloca-larger-than
(and not to have to disable the yet-to-be committed -Walloc-zero
warning) the attached patch makes sure that the alloca calls that
are subject to the warnings always request at least 1 byte.

Thanks
Martin

PS Alloca(0) is not necessarily undefined but the pointer the call
returns need not be distinct from other pointers returned from
other such calls in the same function (and there are compilers
that do not make it distinct).  Relying on the pointer being
distinct could be a source of subtle bugs, hence the warning.
gcc/fortran/ChangeLog:

	* interface.c (compare_actual_formal): Avoid calling alloca with
	an argument of zero.
	* symbol.c (do_traverse_symtree): Same.
	* trans-intrinsic.c (gfc_conv_intrinsic_ishftc): Same.

gcc/ChangeLog:

	* reg-stack.c (subst_asm_stack_regs): Same.
	* tree-ssa-threadedge.c
	(record_temporary_equivalences_from_stmts_at_dest): Same.

diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index a0cb0bb..2da51d7 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -2821,7 +2821,8 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
   for (f = formal; f; f = f->next)
     n++;
 
-  new_arg = XALLOCAVEC (gfc_actual_arglist *, n);
+  /* Take care not to call alloca with a zero argument.  */
+  new_arg = XALLOCAVEC (gfc_actual_arglist *, n + !n);
 
   for (i = 0; i < n; i++)
     new_arg[i] = NULL;
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 0b711ca..cf403c4 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -3979,7 +3979,8 @@ do_traverse_symtree (gfc_symtree *st, void (*st_func) (gfc_symtree *),
 
   gcc_assert ((st_func && !sym_func) || (!st_func && sym_func));
   nodes = count_st_nodes (st);
-  st_vec = XALLOCAVEC (gfc_symtree *, nodes);
+  /* Take care not to call alloca with a zero argument.  */
+  st_vec = XALLOCAVEC (gfc_symtree *, nodes + !nodes);
   node_cntr = 0; 
   fill_st_vector (st, st_vec, node_cntr);
 
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 463bb58..e4715f8 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -5525,7 +5525,8 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
   unsigned int num_args;
 
   num_args = gfc_intrinsic_argument_list_length (expr);
-  args = XALLOCAVEC (tree, num_args);
+  /* Take care not to call alloca with a zero argument.  */
+  args = XALLOCAVEC (tree, num_args + !num_args);
 
   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
 
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 4e86fa9..7da5a5f 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -2050,9 +2050,10 @@ subst_asm_stack_regs (rtx_insn *insn, stack_ptr regstack)
   for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
     i++;
 
-  note_reg = XALLOCAVEC (rtx, i);
-  note_loc = XALLOCAVEC (rtx *, i);
-  note_kind = XALLOCAVEC (enum reg_note, i);
+  /* Take care not to call alloca with a zero argument.  */
+  note_reg = XALLOCAVEC (rtx, i + !i);
+  note_loc = XALLOCAVEC (rtx *, i + !i);
+  note_kind = XALLOCAVEC (enum reg_note, i + !i);
 
   n_notes = 0;
   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 534292c..0564e69 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -340,7 +340,8 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
 	      unsigned int num, i = 0;
 
 	      num = NUM_SSA_OPERANDS (stmt, SSA_OP_ALL_USES);
-	      copy = XALLOCAVEC (tree, num);
+	      /* Take care not to call alloca with a zero argument.  */
+	      copy = XALLOCAVEC (tree, num + !num);
 
 	      /* Make a copy of the uses & vuses into USES_COPY, then cprop into
 		 the operands.  */

Reply via email to