Re: Format warnings ignored by -Wformat

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi!

On Mon, Feb 25, 2019 at 11:18:31AM -0800, Jon Flatley wrote:
> Hello,
> 
> I am doing a some investigation into some of the format options used
> in the upstream Linux Kbuilds in both GCC and Clang. This started when
> I noticed -Wformat is used when building the kernel with GCC, but not
> with Clang. As it turns out, this is important. Enabling format
> warnings in Clang leads to hundreds of warnings when building the
> Linux kernel, see here:
> 
> https://gist.github.com/nathanchance/443db156e56cd3c0f6b21d9d77728d80
> 
> After some more investigating I found a little code snippet that
> demonstrates the discrepancy.
> For example consider the following:
>   int i = 5;
>   printf("%hu\n", i);
>   printf("%zu\n", i);
> 
> GCC produces only one warning under -Wformat on the second print
> statement, where Clang produces warnings for both.
> 
> Compiling that example with GCC under -Wformat prints:
>   format_test.c:7:13: warning: format ‘%zu’ expects argument of type
> ‘size_t’, but argument 2 has type ‘int’ [-Wformat=]
>      printf("%zu\n", i);
>              ~~^
>              %u
> 
> But compiling with Clang under -Wformat prints:
>   format_test.c:6:19: warning: format specifies type 'unsigned short' but the
>         argument has type 'int' [-Wformat]
>     printf("%hu\n", i);
>             ~~~     ^
>             %d
>   format_test.c:7:19: warning: format specifies type 'size_t'
>         (aka 'unsigned long') but the argument has type 'int' [-Wformat]
>     printf("%zu\n", i);
>             ~~~     ^
>             %d
>   2 warnings generated.
> 
> 
> I was hoping I could reach out and gain some insight as to why GCC
> ignores these scenarios where Clang produces warnings. This would be
> very helpful as we move to enable -Wformat for both GCC and Clang in
> the upstream kernel, which is an issue we're tracking here:
> https://github.com/ClangBuiltLinux/linux/issues/378

You cannot pass a short int to a varargs function like printf, it is
always promoted to int.  As the C standard says for the h flag character:

h
    Specifies that a following d, i, o, u, x, or X conversion specifier
    applies to a short int or unsigned short int argument (the argument
    will have been promoted according to the integer promotions, but
    its value shall be converted to short int or unsigned short int
    before printing); or that a following n conversion specifier applies
    to a pointer to a short int argument.

Assuming the integer started out as short int before passing it to the
printf function is something GCC does not do; it will warn on a lot of
perfectly valid code.


Segher



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux