https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79123
Bug ID: 79123
Summary: incorrect -Walloca-larger-than: alloca may be too
large due to conversion from long int to long unsigned
int
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
The -Walloca-larger-than option issues an incorrect/misleading warning for the
following valid test case.
I think there are two problems here: one is that the range information isn't
available for the alloca argument, and the other is the false positive warning
pointing the finger at the conversion. The latter seems to be caused by the
cast_from_signed_p() function in gimple-ssa-warn-alloca.c being based solely on
the type of the right hand side expression of a SSA_NAME_DEF_STMT without
considering that the SSA_NAME may be subsequently bounded.
$ cat z.C && gcc -O2 -S -Walloca-larger-than=100 -xc
-fdump-tree-vrp=/dev/stdout z.C
typedef __SIZE_TYPE__ size_t;
void f (void*);
void g (int *p, int *q)
{
size_t n = (size_t)(p - q);
if (n < 10)
f (__builtin_alloca (n));
}
...
z.C: In function ‘g’:
z.C:10:5: warning: argument to ‘alloca’ may be too large due to conversion from
‘long int’ to ‘long unsigned int’ [-Walloca-larger-than=]
f (__builtin_alloca (n));
^~~~~~~~~~~~~~~~~~~~~~~~
;; Function g (g, funcdef_no=0, decl_uid=1799, cgraph_uid=0, symbol_order=0)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2 3 4
;; 2 succs { 3 4 }
;; 3 succs { 4 }
;; 4 succs { 1 }
SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j
n_13 -> { n_9 }
Incremental SSA update started at block: 2
Number of blocks in CFG: 5
Number of blocks to update: 2 ( 40%)
Value ranges after VRP:
p.0_1: VARYING
q.1_2: VARYING
_3: VARYING
_4: [-2305843009213693952, 2305843009213693951]
_5: ~[0B, 0B]
.MEM_6: VARYING
p_7(D): VARYING
q_8(D): VARYING
n_9: ~[2305843009213693952, 16140901064495857663]
n_13: [0, 9] EQUIVALENCES: { n_9 } (1 elements)
g (int * p, int * q)
{
size_t n;
long int p.0_1;
long int q.1_2;
long int _3;
long int _4;
void * _5;
<bb 2> [100.00%]:
p.0_1 = (long int) p_7(D);
q.1_2 = (long int) q_8(D);
_3 = p.0_1 - q.1_2;
_4 = _3 /[ex] 4;
n_9 = (size_t) _4;
if (n_9 <= 9)
goto <bb 3>; [36.64%]
else
goto <bb 4>; [63.36%]
<bb 3> [36.64%]:
_5 = __builtin_alloca (n_9);
f (_5);
<bb 4> [100.00%]:
return;
}