On 11/25/2016 12:51 PM, Jeff Law wrote:
On 11/23/2016 06:15 PM, Martin Sebor wrote:
gcc_assert works only in some instances (e.g., in c-ada-spec.c:191)
but not in others because some actually do make the alloca(0) call
at runtime: at a minimum, lto.c:3285, reg-stack.c:2008, and
tree-ssa-threadedge.c:344 assert during bootstrap.
You might have the wrong line number of reg-stack.c and lto. You've
pointed to the start of subst_asm_stack_regs and lto_main respectively.
It'd probably be better if you posted the line with a bit of context.
I must have copied the wrong line numbers or had stale sources
in my tree. Sorry about that. In lto.c, there are two calls
to XALLOCAVEC. I believe the first one is the one where the
alloca(0) call takes place:
1580
1581 tree *map = XALLOCAVEC (tree, 2 * len);
1582 for (tree_scc *pscc = *slot; pscc; pscc = pscc->next)
--
1610 {
1611 tree *map2 = XALLOCAVEC (tree, 2 * len);
1612 for (unsigned i = 0; i < len; ++i)
In reg-stack.c it's these three:
2052
2053 note_reg = XALLOCAVEC (rtx, i);
2054 note_loc = XALLOCAVEC (rtx *, i);
2055 note_kind = XALLOCAVEC (enum reg_note, i);
2056
To find all such calls I modified GCC to emit an inform call for
every XALLOCAVEC invocation with a zero argument, configured the
patched GCC on x86_64 with all languages (including lto),
bootstrapped it, ran the full test suite, and extracted the set
of unique notes from the logs. Attached in the .log file is
the output along with counts of each. Curiously, neither of
the two above shows up, even though adding asserts for them
broke bootstrap. I haven't investigated why.
Martin
PS The patch I used to get the output is in the attached .diff
file.
gcc/ada/gcc-interface/utils.c:5623: void def_fn_type(builtin_type, builtin_type, bool, int, ...): alloca called with a zero argument
gcc/calls.c:3260: rtx_def* expand_call(tree, rtx, int): alloca called with a zero argument
gcc/c-family/c-common.c:3914: void def_fn_type(builtin_type, builtin_type, bool, int, ...): alloca called with a zero argument
gcc/cp/call.c:3141: z_candidate* add_template_candidate_real(z_candidate**, tree, tree, tree, tree, const vec<tree_node*, va_gc>*, tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t): alloca called with a zero argument
gcc/cp/pt.c:11362: tree_node* tsubst_template_args(tree, tree, tsubst_flags_t, tree): alloca called with a zero argument
gcc/cp/semantics.c:1444: tree_node* finish_asm_stmt(int, tree, tree, tree, tree, tree): alloca called with a zero argument
gcc/final.c:2632: rtx_insn* final_scan_insn(rtx_insn*, FILE*, int, int, int*): alloca called with a zero argument
gcc/gimple-fold.c:4346: bool fold_stmt_1(gimple_stmt_iterator*, bool, tree_node* (*)(tree)): alloca called with a zero argument
gcc/gimple-fold.c:5852: tree_node* gimple_fold_stmt_to_constant_1(gimple*, tree_node* (*)(tree), tree_node* (*)(tree)): alloca called with a zero argument
gcc/gimple-walk.c:844: bool walk_stmt_load_store_addr_ops(gimple*, void*, walk_stmt_load_store_addr_fn, walk_stmt_load_store_addr_fn, walk_stmt_load_store_addr_fn): alloca called with a zero argument
gcc/tree.c:11260: tree_node* build_call_expr_loc(location_t, tree, int, ...): alloca called with a zero argument
gcc/tree.c:11277: tree_node* build_call_expr(tree, int, ...): alloca called with a zero argument
gcc/tree.c:11312: tree_node* build_call_expr_internal_loc(location_t, internal_fn, tree, int, ...): alloca called with a zero argument
gcc/tree-ssa-structalias.c:4930: void find_func_aliases(function*, gimple*): alloca called with a zero argument
gcc/tree-ssa-threadedge.c:343: gimple* record_temporary_equivalences_from_stmts_at_dest(edge, const_and_copies*, avail_exprs_stack*, tree_node* (*)(gimple*, gimple*, avail_exprs_stack*)): alloca called with a zero argument
CALLS LOCATION
------ --------
226872 /src/gcc/78284/gcc/c-family/c-common.c:3914
117141 /src/gcc/78284/gcc/calls.c:3260
183040 /src/gcc/78284/gcc/cp/call.c:3141
80400 /src/gcc/78284/gcc/ada/gcc-interface/utils.c:5623
17671 /src/gcc/78284/gcc/gimple-fold.c:4346
65348 /src/gcc/78284/gcc/gimple-fold.c:5852
63468 /src/gcc/78284/gcc/tree-ssa-threadedge.c:343
32886 /src/gcc/78284/gcc/gimple-walk.c:844
6578 /src/gcc/78284/gcc/tree-ssa-structalias.c:4930
4046 /src/gcc/78284/gcc/cp/pt.c:11362
4866 /src/gcc/78284/gcc/cp/semantics.c:1444
1484 /src/gcc/78284/gcc/final.c:2632
80 /src/gcc/78284/gcc/tree.c:11312
26 /src/gcc/78284/gcc/tree.c:11260
4 /src/gcc/78284/gcc/tree.c:11277
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 3e3f31e..24c8c32 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -22,6 +22,12 @@ along with GCC; see the file COPYING3. If not see
#include "symtab.h"
+extern void inform (location_t, const char *, ...);
+
+#undef WARN_ALLOCA_ZERO
+#define WARN_ALLOCA_ZERO() \
+ inform (0, "%s:%i: %s: alloca called with a zero argument", \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__)
/* This file contains all the data structures that define the 'tree' type.
There are no accessor macros nor functions in this file. Only the
basic data structures, extern declarations and type definitions. */
diff --git a/include/libiberty.h b/include/libiberty.h
index 605ff56..c293533 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -352,8 +352,11 @@ extern unsigned int xcrc32 (const unsigned char *, int, unsigned int);
#define XDELETE(P) free ((void*) (P))
/* Array allocators. */
+#ifndef WARN_ALLOCA_ZERO
+# define WARN_ALLOCA_ZERO() (void)0
+#endif
-#define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N)))
+#define XALLOCAVEC(T, N) ((N) != 0 ? (T *) alloca (sizeof (T) * (N)) : (WARN_ALLOCA_ZERO (), (T *)0))
#define XNEWVEC(T, N) ((T *) xmalloc (sizeof (T) * (N)))
#define XCNEWVEC(T, N) ((T *) xcalloc ((N), sizeof (T)))
#define XDUPVEC(T, P, N) ((T *) xmemdup ((P), sizeof (T) * (N), sizeof (T) * (N)))