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

Reply via email to