This option is enabled by default when -Wformat option is enabled. A user can specify -Wno-format-int-precision to disable emitting warnings when passing an argument of an incompatible integer type to a 'd', 'i', 'o', 'u', 'x', or 'X' conversion specifier when it has the same precision as the expected type.
Signed-off-by: Daniil Stas <daniil.s...@posteo.net> gcc/c-family/ChangeLog: * c-format.c (check_format_types): Don't emit warnings when passing an argument of an incompatible integer type to a 'd', 'i', 'o', 'u', 'x', or 'X' conversion specifier when it has the same precision as the expected type if -Wno-format-int-precision option is specified. * c.opt: Add -Wformat-int-precision option. gcc/ChangeLog: * doc/invoke.texi: Add -Wformat-int-precision option description. gcc/testsuite/ChangeLog: * c-c++-common/Wformat-int-precision-1.c: New test. * c-c++-common/Wformat-int-precision-2.c: New test. --- Changes for v3: - Added additional @code{} derictives to the documentation where needed. - Changed tests to run on "! long_neq_int" target instead of "lp64". - Added a test case to check that gcc still emits warnings for arguments with different precision even with -Wno-format-int-precision option enabled. Changes for v2: - Changed the option name to -Wformat-int-precision. - Changed the option description as was suggested by Martin. - Changed Wformat-int-precision-2.c to use dg-bogus instead of previous invalid syntax. gcc/c-family/c-format.c | 2 +- gcc/c-family/c.opt | 6 ++++++ gcc/doc/invoke.texi | 17 ++++++++++++++++- .../c-c++-common/Wformat-int-precision-1.c | 7 +++++++ .../c-c++-common/Wformat-int-precision-2.c | 8 ++++++++ 5 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wformat-int-precision-1.c create mode 100644 gcc/testsuite/c-c++-common/Wformat-int-precision-2.c diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index e735e092043..c66787f931f 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -4248,7 +4248,7 @@ check_format_types (const substring_loc &fmt_loc, && (!pedantic || i < 2) && char_type_flag) continue; - if (types->scalar_identity_flag + if ((types->scalar_identity_flag || !warn_format_int_precision) && (TREE_CODE (cur_type) == TREE_CODE (wanted_type) || (INTEGRAL_TYPE_P (cur_type) && INTEGRAL_TYPE_P (wanted_type))) diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 3976fc368db..0621585a4f9 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -684,6 +684,12 @@ C ObjC C++ LTO ObjC++ Warning Alias(Wformat-overflow=, 1, 0) IntegerRange(0, 2) Warn about function calls with format strings that write past the end of the destination region. Same as -Wformat-overflow=1. +Wformat-int-precision +C ObjC C++ ObjC++ Var(warn_format_int_precision) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 1, 0) +Warn when passing an argument of an incompatible integer type to a 'd', 'i', +'o', 'u', 'x', or 'X' conversion specifier even when it has the same precision +as the expected type. + Wformat-security C ObjC C++ ObjC++ Var(warn_format_security) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) Warn about possible security problems with format functions. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 4b1b58318f0..da69d804598 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -351,7 +351,7 @@ Objective-C and Objective-C++ Dialects}. -Werror -Werror=* -Wexpansion-to-defined -Wfatal-errors @gol -Wfloat-conversion -Wfloat-equal -Wformat -Wformat=2 @gol -Wno-format-contains-nul -Wno-format-extra-args @gol --Wformat-nonliteral -Wformat-overflow=@var{n} @gol +-Wformat-nonliteral -Wformat-overflow=@var{n} -Wformat-int-precision @gol -Wformat-security -Wformat-signedness -Wformat-truncation=@var{n} @gol -Wformat-y2k -Wframe-address @gol -Wframe-larger-than=@var{byte-size} -Wno-free-nonheap-object @gol @@ -6113,6 +6113,21 @@ If @option{-Wformat} is specified, also warn if the format string is not a string literal and so cannot be checked, unless the format function takes its format arguments as a @code{va_list}. +@item -Wformat-int-precision +@opindex Wformat-int-precision +@opindex Wno-format-int-precision +Warn when passing an argument of an incompatible integer type to +a @samp{d}, @samp{i}, @samp{o}, @samp{u}, @samp{x}, or @samp{X} conversion +specifier even when it has the same precision as the expected type. +For example, on targets where @code{int64_t} is a typedef for @code{long}, +the warning is issued for the @code{printf} call below even when both +@code{long} and @code{long long} have the same size and precision. + +@smallexample + extern int64_t n; + printf ("%lli", n); +@end smallexample + @item -Wformat-security @opindex Wformat-security @opindex Wno-format-security diff --git a/gcc/testsuite/c-c++-common/Wformat-int-precision-1.c b/gcc/testsuite/c-c++-common/Wformat-int-precision-1.c new file mode 100644 index 00000000000..a06e047c933 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wformat-int-precision-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target { ! long_neq_int } } } */ +/* { dg-options "-Wformat" } */ + +void test () +{ + __builtin_printf ("%d\n", (long) 1); /* { dg-warning "expects argument of type" } */ +} diff --git a/gcc/testsuite/c-c++-common/Wformat-int-precision-2.c b/gcc/testsuite/c-c++-common/Wformat-int-precision-2.c new file mode 100644 index 00000000000..e9b41b4f42e --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wformat-int-precision-2.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target { ! long_neq_int } } } */ +/* { dg-options "-Wformat -Wno-format-int-precision" } */ + +void test () +{ + __builtin_printf ("%d\n", (long) 1); /* { dg-bogus "expects argument of type" } */ + __builtin_printf ("%d\n", (long long) 1); /* { dg-warning "expects argument of type" "" { target int32 } } */ +} -- 2.34.0