The false positives have disappeared thanks to g:520d5ad337eaa15860a5a964daf7ca46cf31c029. I have added the two test cases in the attached diff in r11-8202 after testing on aarch64, arm, powerpc64le, and x86_64, out of an abundance of caution.
Martin
commit 2dbbbe893f75f587c48111ab4c97cf5e74fb91bb Author: Martin Sebor <mse...@redhat.com> 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. diff --git a/gcc/testsuite/gcc.dg/uninit-pr89230-1.c b/gcc/testsuite/gcc.dg/uninit-pr89230-1.c new file mode 100644 index 00000000000..1c07c4f6d78 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr89230-1.c @@ -0,0 +1,25 @@ +/* PR middle-end/89230 - Bogus uninited usage warning with printf + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +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) // { dg-bogus "\\\[-Wmaybe-uninitialized" } + return 2; + } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pr89230-2.c b/gcc/testsuite/gcc.dg/uninit-pr89230-2.c new file mode 100644 index 00000000000..473d2da5d3d --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr89230-2.c @@ -0,0 +1,54 @@ +/* PR middle-end/89230 - Bogus uninited usage warning with printf + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void* memset (void*, int, size_t); +extern int printf (const char*, ...); +extern int rand (void); + +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) { + + printf ("%d\n", s->b); + if (s->a) + printf ("s->a = %d\n", s->a); + else if (!h) + printf ("!h\n"); + else + printf ("h->d = %d\n", h->d); + } +}