Created attachment 44070 [details] testcase The attached creduce'd testcase warns with -Wformat-overflow: $ g++-8 -c -O2 -Wformat-overflow t7.cpp t7.cpp: In function 'void f()': t7.cpp:15:16: warning: '%s' directive writing up to 55 bytes into a region of size 12 [-Wformat-overflow=] t7.cpp:9:10: return c[d]; ~~~~ t7.cpp:15:16: sprintf(e, "xxxxxxxxxxxx %s / %s", "", g); ^~~~~~~~~~~~~~~~~~~~~~ t7.cpp:15:12: note: 'sprintf' output between 17 and 72 bytes into a destination of size 28 sprintf(e, "xxxxxxxxxxxx %s / %s", "", g); ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ But when -fpic or -fPIC is added, the warning vanishes. Current trunk@259927 shows the same behaviour.
I suspect this is due to inlining decision of b::h into f. In PIC mode, b::h is consider overwritable so it is not inclined while in non pic mode it is inlined.
As explained in comment #1, with -fpic extern functions are not considered candidates for inlining because they can be superimposed. Without -fpic GCC sees that the inlined function can return a string that's as long as 55 characters but with the option a superimposed implementation could be guaranteed to return a shorter string. The same effect can be seen with other middle-end warnings, including for example -Warray-bounds with the following modified test case: struct b { const char *h(int) const; char c[4][56]; }; const char *b::h(int d) const { return c[d]; // no -Warray-bounds with -fpic } void f() { b a; __builtin_puts (a.h (99)); }