https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90191
Bug ID: 90191 Summary: [9 regression] -Wformat-overflow depends on --param max-jump-thread-duplication-stmts=17 Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: dimhen at gmail dot com Target Milestone: --- r265568 PASS r265754 FAIL r270458 FAIL Warn if compiled with "-O2 --param max-jump-thread-duplication-stmts=17" And not warn if compiled with -O2 Original code fill & printf() 2 vectors of chars (pseudo-code see below) -- If second vector is in "if() {}" then warning emitted. -- If second vector is out of "if() {}" then no warning produced. -- if printf() divided into 2 printf there are no warning. $ cat a.ii extern "C" int printf(const char *...); struct i { void j(char *p1, int) { delete p1; } }; struct q { typedef char &d; }; struct t { static char *u(); }; template <typename e, typename ab, typename g, typename h> void ad(e, ab, g, h); char *m; struct v { struct w { char *l; }; v(int p1) { int o = p1, a = o; m = a ? t::u() : 0; n.l = m; } ~v() { char *c = n.l, *p = c; int f = 0; i k; k.j(p, f); } w n; }; int s; struct x : v { x() : v(y()) { i b; ad(0, 0, s, b); } q::d operator[](int p1) { return *(n.l + p1); } static int y(); }; unsigned ap(); char r; static int av() { { x d; if (0) goto ay; char &e = d[0]; printf("%s = %s\n", &r, &e); } ay: return 0; } unsigned ap() { av(); return 0; } $ /usr/local/gcc_current/bin/g++ -O2 -fpreprocessed -Wall -Wextra -c a.ii $ /usr/local/gcc_current/bin/g++ -O2 --param max-jump-thread-duplication-stmts=17 -fpreprocessed -Wall -Wextra -c a.ii In function 'int av()', inlined from 'unsigned int ap()' at a.ii:53:5: a.ii:47:11: warning: '%s' directive argument is null [-Wformat-overflow=] 47 | printf("%s = %s\n", &r, &e); | ~~~~~~^~~~~~~~~~~~~~~~~~~~~ Original code looks as size_t l1, l2, sel; if(foo_1(&l1)) goto err; if(foo_2(&sel, &l2)) goto err; std::vector<char> v(l1); if(bar_1(&v[0]) goto err; if(sel) { std::vector<char> w(l2); // <--- if move out of block then warning disappears if(bar_2(&w[0])) goto err; printf("%s = %s\n", &v[0], &w[0]); // <-- if divided to 2 calls then warning disappears return; } err: return; $ /usr/local/gcc_current/bin/g++ -v Using built-in specs. COLLECT_GCC=/usr/local/gcc_current/bin/g++ COLLECT_LTO_WRAPPER=/usr/local/gcc_current/libexec/gcc/x86_64-pc-linux-gnu/9.0.1/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none Target: x86_64-pc-linux-gnu Configured with: /home/dimhen/src/gcc_current/configure --prefix=/usr/local/gcc_current --enable-checking=yes,df,fold,rtl,extra --enable-languages=c,c++,lto --disable-multilib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --with-tune=native Thread model: posix gcc version 9.0.1 20190419 (experimental) [trunk revision 270458] (GCC)