[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #10 from CVS Commits --- The master branch has been updated by Martin Sebor : https://gcc.gnu.org/g:2dbbbe893f75f587c48111ab4c97cf5e74fb91bb commit r11-8202-g2dbbbe893f75f587c48111ab4c97cf5e74fb91bb Author: Martin Sebor Date: Thu Apr 15 14:09:56 2021 -0600 PR middle-end/89230 - Bogus uninited usage warning with printf gcc/testsuite/ChangeLog: * gcc.dg/uninit-pr89230-1.c: New test. * gcc.dg/uninit-pr89230-2.c: Same.
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 Martin Sebor changed: What|Removed |Added Known to fail||10.2.0, 7.3.0, 8.3.0, 9.2.0 Target Milestone|--- |11.0 Resolution|--- |FIXED Status|WAITING |RESOLVED --- Comment #9 from Martin Sebor --- GCC 11 doesn't issue warnings for the test cases in comment #4 or comment #5 anymore. It has disappeared with g:520d5ad337eaa15860a5a964daf7ca46cf31c029. Let me add the test cases to the test suite and resolve this report as fixed.
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #8 from Eric Gallager --- (In reply to Eric Gallager from comment #7) > (In reply to Andrew Pinski from comment #3) > > (In reply to lavr from comment #2) > > > Okay, but "d" points to a clearly separate storage on stack within a local > > > frame. None of the pointers passed to (s)printf() relate to that area > > > (either they are also clearly separate within the current stack frame, > > > automatic ("name", "type", "temp"); or the argument values, that function > > > was called with ("pfx")), so how "d->D_fid[2]" can be changed, in GCC's > > > point of view? I mean, within the semantics of the language, that's > > > impossible; and the warning should only be issued for that kind of a > > > (mis)use. > > > > It is not obvious from your small code snippet that d does not point to a > > local struct or if that local struct does not escape. > > > > Without a full testcase (preprocessed source), it is hard to debug this any > > further. > > Reporter has since provided a full testcase (I haven't made any further > attempt to debug it myself though) ...thus, this bug probably shouldn't be in WAITING any longer... (dunno if that necessarily implies that it should be confirmed, though...)
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #7 from Eric Gallager --- (In reply to Andrew Pinski from comment #3) > (In reply to lavr from comment #2) > > Okay, but "d" points to a clearly separate storage on stack within a local > > frame. None of the pointers passed to (s)printf() relate to that area > > (either they are also clearly separate within the current stack frame, > > automatic ("name", "type", "temp"); or the argument values, that function > > was called with ("pfx")), so how "d->D_fid[2]" can be changed, in GCC's > > point of view? I mean, within the semantics of the language, that's > > impossible; and the warning should only be issued for that kind of a > > (mis)use. > > It is not obvious from your small code snippet that d does not point to a > local struct or if that local struct does not escape. > > Without a full testcase (preprocessed source), it is hard to debug this any > further. Reporter has since provided a full testcase (I haven't made any further attempt to debug it myself though)
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #6 from lavr at ncbi dot nlm.nih.gov --- That said, any function call within the outer "if()" but before the inner "if()" would cause the warning, even if that call does not accept any pointers (and thus cannot alias with local "s"). Modifying the code above to include "fun()" in stead of "printf()", same issue results: ... void fun(int i) { srand(i); } int main(void) { char blk[512], tmp[512]; struct S *s = (struct S*) blk; struct H *h; getblk(blk); if (s->a || !(h = gethdr(tmp)) || s->a != h->d) { #ifdef BUG fun(s->b); #endif ... $ gcc -DBUG -O6 -Wall -c bogus2.c bogus2.c: In function ‘main’: bogus2.c:47:17: warning: ‘h’ may be used uninitialized in this function [-Wmaybe-uninitialized] else if (!h) ^
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #5 from lavr at ncbi dot nlm.nih.gov --- Thank you Martin, for giving me the idea of where the problem might be stemming from! It does look like *printf() is not recognized by GCC as not modifying the local memory. But in your example GCC _might_ think that "p" and "q" can be aliased (being the result of the same function). Below is a mockup of the code that I was dealing with, clearly showing that "s" and "h" cannot be aliased! "s" is being on the local frame all alone. I get the same "uninitialized" warning if BUG is defined: $ cat bogus2.c #include #include #include struct S { int a; int b; }; struct H { int c; int d; }; void getblk(void* blk) { struct S* s = (struct S*) blk; memset(blk, 0, 512); s->a = rand() & 1; } struct H* gethdr(void* blk) { memset(blk, 0, 512); return rand() & 1 ? (struct H*) blk : 0; } int main(void) { char blk[512], tmp[512]; struct S *s = (struct S*) blk; struct H *h; getblk(blk); if (s->a || !(h = gethdr(tmp)) || s->a != h->d) { #ifdef BUG printf("%d\n", s->b); #endif if (s->a) printf("s->a = %d\n", s->a); else if (!h) printf("!h\n"); else printf("h->d = %d\n", h->d); } } $ gcc -O6 -Wall -c bogus2.c $ gcc -DBUG -O6 -Wall -c bogus2.c bogus2.c: In function ‘main’: bogus2.c:42:17: warning: ‘h’ may be used uninitialized in this function [-Wmaybe-uninitialized] else if (!h) ^
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 Martin Sebor changed: What|Removed |Added Keywords||alias CC||msebor at gcc dot gnu.org Depends on||81776 --- Comment #4 from Martin Sebor --- Making GCC aware that printf doesn't modify memory (at least not without %n in the format string, or without addresses in its argument list) is the subject of pr81776. It's hard to tell for sure without more context but a similar (if not the same) problem can be reproduced in the following test case. Uncommenting the attribute makes the warning go away because it tells GCC that the pointer returned from f() and assigned to q does not alias any object in memory, so printf cannot clobber what it points to. With the test case below, I could confirm this bug as a dependency of pr81776. But if your case is different then as Andrew requests, please try to reduce it to a small reproducible test case to show us what's going on there. $ cat z.c && gcc -O2 -S -Wall z.c struct S { int i, j; }; /* attribute__ ((malloc)) */ struct S* f (void); int g (void) { struct S *p = f (), *q; if (p->i || !(q = f ()) || p->j != q->i) { __builtin_printf ("%i", p->i); if (p->i) return 1; if (!q) return 2; } return 0; } z.c: In function ‘g’: z.c:16:9: warning: ‘q’ may be used uninitialized in this function [-Wmaybe-uninitialized] 16 | if (!q) | ^ Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81776 [Bug 81776] missing sprintf optimization due to pointer escape analysis
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 Andrew Pinski changed: What|Removed |Added Status|UNCONFIRMED |WAITING Last reconfirmed||2019-02-07 Ever confirmed|0 |1 --- Comment #3 from Andrew Pinski --- (In reply to lavr from comment #2) > Okay, but "d" points to a clearly separate storage on stack within a local > frame. None of the pointers passed to (s)printf() relate to that area > (either they are also clearly separate within the current stack frame, > automatic ("name", "type", "temp"); or the argument values, that function > was called with ("pfx")), so how "d->D_fid[2]" can be changed, in GCC's > point of view? I mean, within the semantics of the language, that's > impossible; and the warning should only be issued for that kind of a > (mis)use. It is not obvious from your small code snippet that d does not point to a local struct or if that local struct does not escape. Without a full testcase (preprocessed source), it is hard to debug this any further.
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- Okay, but "d" points to a clearly separate storage on stack within a local frame. None of the pointers passed to (s)printf() relate to that area (either they are also clearly separate within the current stack frame, automatic ("name", "type", "temp"); or the argument values, that function was called with ("pfx")), so how "d->D_fid[2]" can be changed, in GCC's point of view? I mean, within the semantics of the language, that's impossible; and the warning should only be issued for that kind of a (mis)use.
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #1 from Andrew Pinski --- So what is happening here is GCC does not know the properties of sprintf/printf to know they can't modify memory therefor GCC cannot figure out d->D_fid[2] does not change from the first if statement to the second one.