public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug analyzer/109635] New: -Wanalyzer-use-of-uninitialized-value false alarm involving adding 8 to index
@ 2023-04-26 16:32 eggert at cs dot ucla.edu
  0 siblings, 0 replies; only message in thread
From: eggert at cs dot ucla.edu @ 2023-04-26 16:32 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 109635
           Summary: -Wanalyzer-use-of-uninitialized-value false alarm
                    involving adding 8 to index
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 54926
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54926&action=edit
compile with -O2 -fanalyzer to reproduce false positive

This is gcc (GCC) 13.0.1 20230401 (Red Hat 13.0.1-0) on x86-64. I ran into this
problem when building Coreutils. Compile the attached program with:

gcc -S -O2 -fanalyzer make-prime-list.i

The output is at the end of this bug report. It's a false alarm, since primes[i
+ 8].p is accessed only when 8 <= i + 8 < nprimes, and every entry from
primes[0] up to (but not including) primes[nprimes] is initialized by the call
to process_prime.

If you change both instances of 'i + 8' to 'i + 1' in line 1997, the false
alarm goes away. The false alarm is present if you use 'i + 2', though. I don't
know why the problem starts occuring between i + 1 and i + 2.

Here's the output:

make-prime-list.i: In function ‘output_primes’:
make-prime-list.i:1997:56: warning: use of uninitialized value ‘*primes_42(D) +
_3.p’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
 1997 |       unsigned int d8 = i + 8 < nprimes ? primes[i + 8].p - primes[i].p
: 0xff;
      |                                           ~~~~~~~~~~~~~^~
  ‘main’: events 1-6
    |
    | 2038 | main (int argc, char **argv)
    |      | ^~~~
    |      | |
    |      | (1) entry to ‘main’
    |......
    | 2045 |   if (argc != 2)
    |      |      ~
    |      |      |
    |      |      (2) following ‘false’ branch (when ‘argc == 2’)...
    |......
    | 2055 |   limit = atoi (argv[1]);
    |      |           ~~~~~~~~~~~~~~
    |      |           |
    |      |           (3) ...to here
    | 2056 |   if (limit < 3)
    |      |      ~
    |      |      |
    |      |      (4) following ‘false’ branch...
    |......
    | 2060 |   if ( !(limit & 1))
    |      |         ~~~~~~~~~~~
    |      |                |
    |      |                (5) ...to here
    |......
    | 2063 |   sieve = xalloc (size);
    |      |           ~~~~~~~~~~~~~
    |      |           |
    |      |           (6) calling ‘xalloc’ from ‘main’
    |
    +--> ‘xalloc’: events 7-9
           |
           | 2025 | xalloc (size_t s)
           |      | ^~~~~~
           |      | |
           |      | (7) entry to ‘xalloc’
           |......
           | 2028 |   if (p)
           |      |      ~
           |      |      |
           |      |      (8) following ‘true’ branch (when ‘p’ is non-NULL)...
           | 2029 |     return p;
           |      |            ~
           |      |            |
           |      |            (9) ...to here
           |
    <------+
    |
  ‘main’: events 10-11
    |
    | 2063 |   sieve = xalloc (size);
    |      |           ^~~~~~~~~~~~~
    |      |           |
    |      |           (10) returning to ‘main’ from ‘xalloc’
    | 2064 |   memset (sieve, 1, size);
    | 2065 |   prime_list = xalloc (size * sizeof (*prime_list));
    |      |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                |
    |      |                (11) calling ‘xalloc’ from ‘main’
    |
    +--> ‘xalloc’: events 12-15
           |
           | 2025 | xalloc (size_t s)
           |      | ^~~~~~
           |      | |
           |      | (12) entry to ‘xalloc’
           | 2026 | {
           | 2027 |   void *p = malloc (s);
           |      |             ~~~~~~~~~~
           |      |             |
           |      |             (13) region created on heap here
           | 2028 |   if (p)
           |      |      ~
           |      |      |
           |      |      (14) following ‘true’ branch (when ‘p’ is non-NULL)...
           | 2029 |     return p;
           |      |            ~
           |      |            |
           |      |            (15) ...to here
           |
    <------+
    |
  ‘main’: events 16-19
    |
    | 2065 |   prime_list = xalloc (size * sizeof (*prime_list));
    |      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                |
    |      |                (16) returning to ‘main’ from ‘xalloc’
    | 2066 |   nprimes = 0;
    | 2067 |   for (i = 0; i < size;)
    |      |               ~~~~~~~~
    |      |                 |
    |      |                 (17) following ‘true’ branch (when ‘i < size’)...
    | 2068 |     {
    | 2069 |       unsigned p = 3 + 2 * i;
    |      |                    ~~~~~~~~~
    |      |                      |
    |      |                      (18) ...to here
    | 2070 |       unsigned j;
    | 2071 |       process_prime (&prime_list[nprimes++], p);
    |      |       ~
    |      |       |
    |      |       (19) inlined call to ‘process_prime’ from ‘main’
    |
    +--> ‘process_prime’: event 20
           |
           | 1956 |   info->pinv = binvert (p);
           |      |                ^~~~~~~~~~~
           |      |                |
           |      |                (20) calling ‘binvert’ from ‘main’
           |
         ‘binvert’: events 21-22
           |
           | 1940 | binvert (wide_uint a)
           |      | ^~~~~~~
           |      | |
           |      | (21) entry to ‘binvert’
           |......
           | 1946 |       if (y == x)
           |      |          ~
           |      |          |
           |      |          (22) following ‘false’ branch (when ‘x != y’)...
           |
         ‘binvert’: event 23
           |
           |cc1:
           | (23): ...to here
           |
    <------+
    |
  ‘main’: event 24
    |
    | 2071 |       process_prime (&prime_list[nprimes++], p);
    |      |       ^
    |      |       |
    |      |       (24) inlined call to ‘process_prime’ from ‘main’
    |
    +--> ‘process_prime’: event 25
           |
           | 1956 |   info->pinv = binvert (p);
           |      |                ^~~~~~~~~~~
           |      |                |
           |      |                (25) returning to ‘main’ from ‘binvert’
           |
    <------+
    |
  ‘main’: events 26-28
    |
    | 2072 |       for (j = (p * p - 3) / 2; j < size; j += p)
    |      |                                 ~~^~~~~~
    |      |                                   |
    |      |                                   (26) following ‘true’ branch...
    | 2073 |         sieve[j] = 0;
    |      |              ~
    |      |              |
    |      |              (27) ...to here
    |......
    | 2077 |   output_primes (prime_list, nprimes);
    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |   |
    |      |   (28) calling ‘output_primes’ from ‘main’
    |
    +--> ‘output_primes’: events 29-36
           |
           | 1984 | output_primes (const struct prime *primes, unsigned
nprimes)
           |      | ^~~~~~~~~~~~~
           |      | |
           |      | (29) entry to ‘output_primes’
           |......
           | 1991 |   for (wide_uint_bits = 0; mask; wide_uint_bits++)
           |      |                            ~~~~
           |      |                            |
           |      |                            (30) following ‘true’ branch
(when ‘mask != 0’)...
           | 1992 |     mask >>= 1;
           |      |     ~~~~~~~~~~
           |      |          |
           |      |          (31) ...to here
           |......
           | 1995 |   for (i = 0, p = 2; i < nprimes; i++)
           |      |                      ~~~~~~~~~~~
           |      |                        |
           |      |                        (32) following ‘true’ branch (when
‘i < nprimes’)...
           | 1996 |     {
           | 1997 |       unsigned int d8 = i + 8 < nprimes ? primes[i + 8].p -
primes[i].p : 0xff;
           |      |                        
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                           |                        |   |   
            |
           |      |                           |                        |   |   
            (34) following ‘true’ branch...
           |      |                           |                        |   (36)
use of uninitialized value ‘*primes_42(D) + _3.p’ here
           |      |                           (33) ...to here          (35)
...to here
           |

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-26 16:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-26 16:32 [Bug analyzer/109635] New: -Wanalyzer-use-of-uninitialized-value false alarm involving adding 8 to index eggert at cs dot ucla.edu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).