Bruno Haible <[email protected]> writes:

> Using the modified test program:
>
> #include <stdio.h>
> int
> main (void)
> {
>   fprintf (stdout, "%s", NULL);
>   fprintf (stdout, "\n");
>   return 0;
> }
>
> On GNU/Linux:
>
> $ gcc foo.c
> $ ./a.out 
> Segmentation fault (core dumped)
> $ nm a.out | grep ' U '
>                  U fputc@GLIBC_2.2.5
>                  U fputs@GLIBC_2.2.5
>                  U __libc_start_main@GLIBC_2.34
>
> So, due to GCC optimizations, using NULL as argument for %s is unreliable
> even on systems with glibc.

Interesting. Based on the comment above the function that performs this
optimization, this seems like a bug [1]:

    /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
       FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
       more than 3 arguments, and ARG may be null in the 2-argument case.
    
       Return NULL_TREE if no simplification was possible, otherwise return the
       simplified form of the call as a tree.  FCODE is the BUILT_IN_*
       code of the function to be simplified.  */

Later below, it looks like there is an attempt to check if the argument
is NULL:

  /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
  else if (strcmp (fmt_str, target_percent_s) == 0)
    {
      if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
        return false;

>> However, it appears the m4/*printf.m4 files do not check for the
>> behavior so we cannot depend on it.
>> 
>> Bruno, do you recall if this was intentional? Or do you think it should
>> be added?
>
> It is intentional, because that glibc feature is not specified by POSIX.
> It should not be added, because you can't rely on it anyway, due to GCC
> optimizations.

Yes, even if it is a bug every GCC version behaves that way. So lets
leave it as is.

Collin

[1] https://github.com/gcc-mirror/gcc/blob/master/gcc/gimple-fold.cc#L3755

Reply via email to