[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 Martin Sebor changed: What|Removed |Added Priority|P3 |P2 --- Comment #9 from Martin Sebor --- The same problem affects _FORTIFY_SOURCE. Since this effectively disables compile-time buffer overflow detection for the sprintf family of functions I'm bumping Importance up to P2. (The runtime prevention still works.) $ (set -x && cat pr79062.c && gcc -D_FORTIFY_SOURCE=2 -O2 -Wall -flto -c pr79062.c && gcc -D_FORTIFY_SOURCE=2 -O2 -Wall -flto pr79062.o && ./a.out) + cat pr79062.c #include #include int main (void) { char *d = (char*)alloca (2); int n = sprintf (d, "%i", 123); // missing warning with -flto puts (d); if (n > 1) abort (); } + gcc -D_FORTIFY_SOURCE=2 -O2 -Wall -flto -c pr79062.c + gcc -D_FORTIFY_SOURCE=2 -O2 -Wall -flto pr79062.o + ./a.out *** buffer overflow detected ***: ./a.out terminated
[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 Martin Sebor changed: What|Removed |Added Last reconfirmed|2017-01-12 00:00:00 |2021-7-30 Known to fail||10.2.0, 11.2.0, 12.0, ||7.3.0, 8.3.0, 9.2.0 --- Comment #8 from Martin Sebor --- Reconfirmed with GCC 12 for the missing -Wformat-overflow: $ (cc='/build/gcc-master/gcc/xgcc -B /build/gcc-master/gcc'; set -x && cat pr79062.c && $cc -O2 -Wall -flto -c pr79062.c && $cc -O2 -Wall -flto pr79062.o && valgrind ./a.out) + cat pr79062.c int main (void) { char *d = (char*)__builtin_alloca (2); int n = __builtin_sprintf (d, "%i", 123); // missing warning with -flto __builtin_puts (d); if (n > 1) __builtin_abort (); } + /build/gcc-master/gcc/xgcc -B /build/gcc-master/gcc -O2 -Wall -flto -c pr79062.c + /build/gcc-master/gcc/xgcc -B /build/gcc-master/gcc -O2 -Wall -flto pr79062.o + valgrind ./a.out ==5314== Memcheck, a memory error detector ==5314== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==5314== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==5314== Command: ./a.out ==5314== 123 ==5314== ==5314== Process terminating with default action of signal 6 (SIGABRT): dumping core ==5314==at 0x48A357F: raise (in /usr/lib64/libc-2.28.so) ==5314==by 0x488D894: abort (in /usr/lib64/libc-2.28.so) ==5314==by 0x4010A6: main (in /ssd/build/tmp/a.out) ==5314== ==5314== HEAP SUMMARY: ==5314== in use at exit: 0 bytes in 0 blocks ==5314== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ==5314== ==5314== All heap blocks were freed -- no leaks are possible ==5314== ==5314== For lists of detected and suppressed errors, rerun with: -s ==5314== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 --- Comment #7 from Martin Sebor --- It's not completely fixed yet. The warning passes do run with LTO but LTO still runs with warnings disabled unless they are explicitly enabled on the command line. -Walloca-larger-than is not in -Wall or -Wextra so it looks like it works, but -Wformat-overflow is in -Wall and it's not issued when -Wall alone is specified. Richard had a suggestion for how to fix it on gcc-patches but I haven't gotten around to looking into it yet. $ (set -x && cat t.c && for lto in '' '-flto'; do /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -O2 -Wall -Walloca-larger-than=1 $lto -c t.c && /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -O2 -Wall -Walloca-larger-than=1 $lto t.o; done) + cat t.c int main (void) { char *d = (char*)__builtin_alloca (2); __builtin_sprintf (d, "%i", 123); __builtin_puts (d); } + for lto in ''\'''\''' ''\''-flto'\''' + /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -O2 -Wall -Walloca-larger-than=1 -c t.c t.c: In function ‘main’: t.c:3:9: warning: argument to ‘alloca’ is too large [-Walloca-larger-than=] char *d = (char*)__builtin_alloca (2); ^ t.c:3:9: note: limit is 1 bytes, but argument is 2 t.c:4:26: warning: ‘%i’ directive writing 3 bytes into a region of size 2 [-Wformat-overflow=] __builtin_sprintf (d, "%i", 123); ^~ t.c:4:3: note: ‘__builtin_sprintf’ output 4 bytes into a destination of size 2 __builtin_sprintf (d, "%i", 123); ^~~~ + /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -O2 -Wall -Walloca-larger-than=1 t.o + for lto in ''\'''\''' ''\''-flto'\''' + /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -O2 -Wall -Walloca-larger-than=1 -flto -c t.c + /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -O2 -Wall -Walloca-larger-than=1 -flto t.o t.c: In function ‘main’: t.c:3:9: warning: argument to ‘alloca’ is too large [-Walloca-larger-than=] char *d = (char*)__builtin_alloca (2); ^ t.c:3:9: note: limit is 1 bytes, but argument is 2
[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 Wilco changed: What|Removed |Added CC||wilco at gcc dot gnu.org --- Comment #6 from Wilco --- This looks fixed now, gcc.dg/pr78768.c XPASSes on ARM/AArch64 in all configurations. Is this expected so we can fix the test?
[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 Bernd Edlinger changed: What|Removed |Added CC||bernd.edlinger at hotmail dot de --- Comment #5 from Bernd Edlinger --- (In reply to Martin Sebor from comment #3) > The following allows the format string to be recognized even with LTO. The > sprintf pass runs and seems to work correctly, but warnings from it for some > reason do not appear on output. It's as if they were disabled. I'm not > sure what's causing that. > > diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c > index 85f97b2..687a87f 100644 > --- a/gcc/gimple-ssa-sprintf.c > +++ b/gcc/gimple-ssa-sprintf.c > @@ -373,7 +373,16 @@ get_format_string (tree format, location_t *ploc) >if (TREE_CODE (format) != STRING_CST) > return NULL; > > - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format))) != char_type_node) > + tree type = TREE_TYPE (format); > + if (TREE_CODE (type) == ARRAY_TYPE) > +type = TREE_TYPE (type); > + > + /* Can't just test that: > + TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format))) != char_type_node > + See bug 79062. */ > + if (TREE_CODE (type) != INTEGER_TYPE > + || TYPE_MODE (type) != TYPE_MODE (char_type_node) > + || TYPE_PRECISION (type) != TYPE_PRECISION (char_type_node)) > { >/* Wide format string. */ >return NULL; That looks wrong. Does that mean that LTO creates a different char type, i.e. other than char_type_node, signed_char_type_node and unsigned_char_type_node ? I think that would also break the TBAA machinery: alias_set_type gimple_get_alias_set (tree t) { /* That's all the expressions we handle specially. */ if (!TYPE_P (t)) return -1; /* For convenience, follow the C standard when dealing with character types. Any object may be accessed via an lvalue that has character type. */ if (t == char_type_node || t == signed_char_type_node || t == unsigned_char_type_node) return 0; which is used in LTO and relies on the same.
[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 --- Comment #4 from Martin Sebor --- All of warn_format, warn_format_overflow, and warn_format_trunc are, in fact, zero in gimple-ssa-sprintf.c when -flto is set. At least one problem is the dependency of -Wformat-{overflow,truncation} in c-common/c.opt on -Wformat, which in turn depends on -Wall. I.e., -Wformat-overflow is LangEnabledBy(C ObjC C++ ObjC++, Wformat=, warn_format >= 1, 0), and doesn't mention LTO. -Wformat depends on -Wall, neither of which mentions LTO. Adding LTO helps somewhat, in that explicitly specifying -Wformat-overflow (or -truncation) enables the warning, but specifying -Wformat or -Wall doesn't have the same effect. To set flags based on dependencies among options the C front end calls the generated C_handle_option_auto() function in $objdir/gcc/options.c which initializes its set of options. There is an LTO_handle_option_auto() in $objdir/gcc/options.c as well but nothing seems to call it. So it looks like some basic pieces aren't hooked up quite right for LTO.
[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 --- Comment #3 from Martin Sebor --- The following allows the format string to be recognized even with LTO. The sprintf pass runs and seems to work correctly, but warnings from it for some reason do not appear on output. It's as if they were disabled. I'm not sure what's causing that. diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 85f97b2..687a87f 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -373,7 +373,16 @@ get_format_string (tree format, location_t *ploc) if (TREE_CODE (format) != STRING_CST) return NULL; - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format))) != char_type_node) + tree type = TREE_TYPE (format); + if (TREE_CODE (type) == ARRAY_TYPE) +type = TREE_TYPE (type); + + /* Can't just test that: + TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format))) != char_type_node + See bug 79062. */ + if (TREE_CODE (type) != INTEGER_TYPE + || TYPE_MODE (type) != TYPE_MODE (char_type_node) + || TYPE_PRECISION (type) != TYPE_PRECISION (char_type_node)) { /* Wide format string. */ return NULL;
[Bug lto/79062] -Walloca-larger-than and -Wformat-overflow warnings disabled by -flto
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79062 Martin Sebor changed: What|Removed |Added Summary|-Wformat-length warnings|-Walloca-larger-than and |disabled by -flto |-Wformat-overflow warnings ||disabled by -flto --- Comment #2 from Martin Sebor --- The latter warning has been renamed to -Wformat-overflow (and -Wformat-truncation). Adjusting Summary.