Bug 80824 - Missing -Wuninitialized at -O0 due to conservative aliasing assumptions
Summary: Missing -Wuninitialized at -O0 due to conservative aliasing assumptions
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.1.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2017-05-19 07:08 UTC by Dima Kogan
Modified: 2021-04-02 00:01 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 10.2.0, 11.0, 7.3.0, 8.3.0, 9.2.0
Last reconfirmed: 2021-04-02 00:00:00


Attachments
test case (189 bytes, text/plain)
2017-05-19 07:08 UTC, Dima Kogan
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dima Kogan 2017-05-19 07:08:17 UTC
Created attachment 41387 [details]
test case

Hi.

I'm using gcc 7.1.0 from Debian/experimental (Debian package gcc-7 version 7.1.0-5).


I ran into a case where an uninitialized variable could be returned from a function without triggering a warning. With the attached minimized source tst.c the following does not yield a warning:

  gcc-7 -DCALL -DTEST2 -Wall -Wextra -o /dev/null -c tst.c

Here I initialize some parts of the S structure (s.x), but not others (s.y). And I return the uninitialized piece: s.y. The extra f() call at the beginning of g() triggers the bug: taking that call out with

  gcc-7 -DTEST2 -Wall -Wextra -o /dev/null -c tst.c

produces the warning as it should.

Furthermore, initializing s.x in a slightly different way makes the bug go away as well: this produces the warning also:

  gcc-7 -DCALL -Wall -Wextra -o /dev/null -c tst.c

Finally, it looks like gcc-6 had a similar issue where the extra call to f() makes the warning go away, but it was fixed in gcc-7: the following misses the warning:

  gcc-6 -DCALL -DTEST2 -Wall -Wextra -o /dev/null -c tst.c

Maybe the fix to THIS bug would be similar. Thanks!
Comment 1 Andrew Pinski 2017-05-20 06:28:59 UTC
There might be another bug already for this one.
Comment 2 Dima Kogan 2019-09-22 07:15:21 UTC
I just tried this with Debian builds of gcc8 and gcc9: 8.3.0-19 and 9.2.1-8. This bug still exists in both.
Comment 3 Martin Sebor 2021-04-02 00:01:59 UTC
Confirmed with GCC 11 and the slightly smaller test case below.  With -O0, the warning is issued in the first case because GCC sees the initialization modifies just the two array elements and not s.b.  It's not issued in the second case because the warning relies on the optimizer infrastructure to tell it if s.b might be modified and because the optimizer doesn't run at -O0 the constant values aren't propagated into the array dereferences and so the infrastructure (exceedingly conservatively) assumes that the accesses to s.a might modify other members of s.  This is a downside of warnings using the same conservative assumptions as optimizers must.

To do better, the warning would have to avoid some of these conservative assumptions.  This isn't really a bug but a limitation inherent in most of these warnings.

$ cat z.c && gcc -S -Wall z.c
void f (void);

int g (void)
{
  f ();

  struct S { int a[2], b; } s;
  enum { i = 0, j = 1 };
  s.a[i] = 0;
  s.a[j] = 0;

  return s.b;    // -Wuninitialized
}

int h (void)
{
  f ();

  struct S { int a[2], b; } s;
  int i = 0, j = 1;
  s.a[i] = 0;
  s.a[j] = 0;

  return s.b;    // missing warning
}

z.c: In function ‘g’:
z.c:12:11: warning: ‘s.b’ is used uninitialized [-Wuninitialized]
   12 |   return s.b;    // -Wuninitialized
      |          ~^~
z.c:7:29: note: ‘s’ declared here
    7 |   struct S { int a[2], b; } s;
      |                             ^