https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81592

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-07-27
                 CC|                            |msebor at gcc dot gnu.org
          Component|rtl-optimization            |tree-optimization
     Ever confirmed|0                           |1

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
Confirmed, even without the sanitizer.  This is another case where the range
information computed by the value range propagation pass is not exposed outside
of it.  The same problem causes a false positive with -Walloca-larger-than but
interestingly not with -Wstringop-overflow which sees the right range.

To avoid the false positive cast the argument to unsigned int and use %u to
format it.  For whatever reason, the cast exposes the correct range even after
VRP1.

The -Walloca and -Wformat-overflow passes run after VRP1 but before VRP2 so the
range must become available then.  I at one point looked into running the
-Wformat-overflow pass later but, IIRC, ran into some problems.  It might be
worth looking into again.  Then again, I'm thinking about running the pass as
part of strlen which also runs before VRP2, so relying on running it that late
would prevent it from using the strlen pass data.

$ cat x.c && gcc-7 -O2 -S -Wall -Walloca-larger-than=59 x.c
void f (void*);

void g (long expiry, long now)
{
  unsigned long timo;

  if (now < expiry) {
    timo = expiry - now;
    if (timo < 60)
      f (__builtin_alloca (timo));
  }
}

void h (long expiry, long now)
{
  unsigned long timo;

  if (now < expiry) {
    timo = expiry - now;
    if (timo < 60)
      f (__builtin_memset (&now + 1, 0, timo));
  }
}

x.c: In function ‘g’:
x.c:10:7: warning: unbounded use of ‘alloca’ [-Walloca-larger-than=]
       f (__builtin_alloca (timo));
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~
x.c: In function ‘h’:
x.c:21:7: warning: ‘__builtin_memset’: writing between 1 and 59 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
       f (__builtin_memset (&now + 1, 0, timo));
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


The top of trunk also prints the following for the alloca case (not sure what's
changed since 7.1):

x.c: In function ‘g’:
x.c:10:7: warning: argument to ‘alloca’ may be too large
[-Walloca-larger-than=]
       f (__builtin_alloca (timo));
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~
x.c:10:7: note: limit is 59 bytes, but argument may be as large as
9223372036854775807

Reply via email to