https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77837
Bug ID: 77837 Summary: missing -Wformat-length warning for %p with null argument on powerpc64 Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- When configured for most *-linux targets with Glibc, including s390x, sparc, and x86_64, GCC prints the warnings below for the following program as expected because Glibc %p formats null arguments as "(nil)": $ cat t.c && /build/sysroot/sparc-unknown-linux/bin/sparc-unknown-linux-gcc -S -Wall t.c char d[5]; void f (void) { __builtin_sprintf (d + 0, "%p", (void*)0); __builtin_sprintf (d + 4, "%p", (void*)0); } t.c: In function 'f': t.c:5:32: warning: writing a terminating nul past the end of the destination [-Wformat-length=] __builtin_sprintf (d + 0, "%p", (void*)0); ~~^ t.c:5:3: note: format output 6 bytes into a destination of size 5 __builtin_sprintf (d + 0, "%p", (void*)0); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t.c:6:30: warning: '%p' directive writing 5 bytes into a region of size 1 [-Wformat-length=] __builtin_sprintf (d + 4, "%p", (void*)0); ^~ t.c:6:3: note: format output 6 bytes into a destination of size 1 __builtin_sprintf (d + 4, "%p", (void*)0); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ However, when configured for powerpc64* (either as a native compiler or a cross-compiler), it prints just the following, indicating that it thinks that %p with a null argument produces a single digit, which is contrary to the Glibc implementation: t.c:6:32: warning: writing a terminating nul past the end of the destination [-Wformat-length=] __builtin_sprintf (d + 4, "%p", (void*)0); ~~^ t.c:6:3: note: format output 2 bytes into a destination of size 1 __builtin_sprintf (d + 4, "%p", (void*)0); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This appears to be because the %p format expected by GCC is determined by a printf_pointer_format target hook which is initialized to the gnu_libc_printf_pointer_format function in most back ends for Linux except in rs6000.o. There it's initialized to the default_printf_pointer_format function. The target hook initialization is the result of expanding the TARGET_PRINTF_POINTER_FORMAT macro, which is defined to gnu_libc_printf_pointer_format in the config/linux.h header. This header is, in turn, included by most back ends for Linux but not by rs6000.c