On Thu, 2025-01-30 at 09:03 +0000, Jonathan Wakely via Gcc wrote:
> On Thu, 30 Jan 2025, 09:00 Dmitry Antipov, <dmanti...@yandex.ru>
> wrote:
> 
> > With (probably) -Wmaybe-uninitialized and/or -Wextra, shouldn't the
> > compiler emit
> > warning about possibly uninitialized 'y' passed to 'ddd()' in the
> > example
> > below?
> > 
> 
> Warnings are always going to be somewhat unreliable. You need a
> proper
> static analyser to detect all problems on all possible paths (-
> fanalyzer
> might do better here, I didn't check).

FWIW -fanalyzer doesn't warn:
  https://godbolt.org/z/EvcnMv767

unless I add -fno-analyzer-state-merge
  https://godbolt.org/z/dr1eTGj53

which gives:

<source>: In function 'aaa':
<source>:24:9: warning: use of uninitialized value 'y' [CWE-457] 
[-Wanalyzer-use-of-uninitialized-value]
   24 |    x += ddd (t, y);      /* then 'y' is passed to ddd() uninitialized */
      |         ^~~~~~~~~~
  'aaa': events 1-7
   13 |    int x = 0, y;         /* 'y' is uninitialized */
      |               ^
      |               |
      |               (1) region created on stack here
      |               (2) capacity: 4 bytes
   14 | 
   15 |    if (t->a)             /* if this condition is true */
      |       ~        
      |       |
      |       (3) following 'true' branch... ─>─┐
      |                                         │
      |                                         │
      |┌────────────────────────────────────────┘
   16 |│     goto l;
      |│     ~~~~      
      |│     |
      |└────>(4) ...to here
......
   21 |    if (t->b)             /* and this condition is false */
      |       ~        
      |       |
      |       (5) following 'false' branch... ─>─┐
      |                                          │
......
      |                                          │
      |┌─────────────────────────────────────────┘
   24 |│   x += ddd (t, y);      /* then 'y' is passed to ddd() uninitialized */
      |│        ~~~~~~~~~~
      |│        |
      |└───────>(6) ...to here
      |         (7) ⚠️  use of uninitialized value 'y' here


Arguably the state-merging code could be smarter here; I haven't
investigated the details, but have filed it as PR analyzer/118702
here:
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118702

Thanks
Dave

> 
> 
> 
> > struct T {
> >    int a;
> >    int b;
> > };
> > 
> > extern int bbb (struct T *, int *);
> > extern int ccc (struct T *, int *);
> > extern int ddd (struct T *, int);
> > 
> > int
> > aaa (struct T *t)
> > {
> >    int x = 0, y;         /* 'y' is uninitialized */
> > 
> >    if (t->a)             /* if this condition is true */
> >      goto l;
> > 
> >    x += bbb (t, &y);
> > 
> >   l:
> >    if (t->b)             /* and this condition is false */
> >        x += ccc (t, &y);
> > 
> >    x += ddd (t, y);      /* then 'y' is passed to ddd()
> > uninitialized */
> > 
> >    return x;
> > }
> > 
> > Dmitry
> > 
> > 
> 

Reply via email to