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;

}

Reply via email to