[Bug c/78512] [7 Regression] r242674 miscompiles Linux kernel

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Nov 24 19:26:00 GMT 2016


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78512

--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
The show_tx_maxrate and show_trans_timeout functions mentioned in the listing
in comment #1 are defined in Linux's net/core/net-sysfs.c.  They return
"sprintf(buf, "%lu\n", queue->tx_maxrate)"  and "sprintf(buf, "%lu",
trans_timeout)" respectively.  Based on the assembly it looks like GCC
determined their argument to be a positive number less than 10 and substituted
it for the function's actual return value.  I don't see anything wrong with
that and it's unlikely that the implementation of integer formatting in the
kernel is different than what C specifies, or that there's a bug in this area
in GCC.

But the printf code in the kernel (x86/boot/printf.c) that formats pointers
does look like it will produce significantly different output than GCC expects
from Glibc on Linux.  Glibc formats non-null pointers the same as integers
using the "%#zx" directive, and null as "(nil)".  Linux uses "%08zx" for all of
them (in LP64).

The printf implementation elsewhere in Linux (lib/vsprintf.c) has a comment it
follows C99 but has many %p extensions.  When that one is used, GCC should
probably bail when %p is encountered.  Alternatively, GCC could add support for
the kernel %p extensions and provide an option to turn them on.  I count 2,364
occurrences of %p in Linux .c files, and 4,486 integer directives, with 1,135
format strings containing both.  So it seems that to let the kernel fully
benefit from the -Wformat-length and -fprintf-return-value options, we should
consider adding support for the extended %p directives.


More information about the Gcc-bugs mailing list