On Thu, 18 Nov 2021, Giuliano Belinassi wrote:

> The `configure` scripts generated with autoconf often tests compiler
> features by setting output to `/dev/null`, which then sets the dump
> folder as being /dev/* and the compilation halts with an error because
> GCC cannot create files in /dev/. This is a problem when configure is
> testing for compiler features because it cannot tell if the failure was
> due to unsupported features or any other problem, and disable it even
> if it is working.
> 
> As an example, running configure overriding CFLAGS="-fdump-ipa-clones"
> will result in several compiler-features as being disabled because of
> gcc halting with an error creating files in /dev/*.
> 
> This commit fixes this issue by checking if the output file is
> /dev/null or /dev/zero. In this case we use the current working
> directory for dump output instead of the directory of the output
> file because we cannot write to /dev/*.

Comments below.

> gcc/ChangeLog
> 2021-11-16  Giuliano Belinassi  <gbelina...@suse.de>
> 
>       * gcc.c (process_command): Skip dumpdir override on -o /dev/null
>         or -o /dev/zero.
> 
> gcc/testsuite/ChangeLog
> 2021-11-16  Giuliano Belinassi  <gbelina...@suse.de>
> 
>       * gcc.dg/devnull-dump.c: New.
> 
> Signed-off-by: Giuliano Belinassi <gbelina...@suse.de>
> ---
>  gcc/doc/invoke.texi                 |  4 +++-
>  gcc/gcc.c                           | 19 +++++++++++++++----
>  gcc/testsuite/gcc.dg/devnull-dump.c |  7 +++++++
>  3 files changed, 25 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/devnull-dump.c
> 
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 6070288856c..4c056606e0c 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -1877,7 +1877,9 @@ named @file{dir/bar.*}, combining the given 
> @var{dumppfx} with the
>  default @var{dumpbase} derived from the primary output name.  Dump
>  outputs also take the input name suffix: @file{dir/bar.c.*}.
>  
> -It defaults to the location of the output file; options
> +It defaults to the location of the output file, unless @option{-o /dev/null}
> +or @option{-o /dev/zero} is passed to the compiler: on those cases the 
> @option{cwd}
> +will be used instead. Options

"It defaults to the location of the output file, unless the output
file is a special file like @code{/dev/null}."

>  @option{-save-temps=cwd} and @option{-save-temps=obj} override this
>  default, just like an explicit @option{-dumpdir} option.  In case
>  multiple such options are given, the last one prevails:
> diff --git a/gcc/gcc.c b/gcc/gcc.c
> index 506c2acc282..0173018ac04 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -5109,10 +5109,21 @@ process_command (unsigned int decoded_options_count,
>      {
>        free (dumpdir);
>        dumpdir = NULL;
> -      temp = lbasename (output_file);
> -      if (temp != output_file)
> -     dumpdir = xstrndup (output_file,
> -                         strlen (output_file) - strlen (temp));
> +      if (strcmp(output_file, "/dev/null") == 0
> +       || strcmp(output_file, "/dev/zero") == 0)

Please merge this into the condition of the block and update the comment

  /* If -save-temps=obj and -o name, create the prefix to use for %b.
     Otherwise just make -save-temps=obj the same as -save-temps=cwd.  */
  else if (save_temps_flag != SAVE_TEMPS_CWD && output_file != NULL)

please split out

          strcmp(output_file, "/dev/null") == 0
          || strcmp(output_file, "/dev/zero") == 0

into a bool special_output_location (const char *) function.  For
example on Windows the special output location would be NUL
(appearantly any path ending in NUL works like that - huh).

Note it might be possible to stat() the file and simply behave
this way whenever it exists and is not a regular file.  For start
just matching literal /dev/null is good enough IMHO (did you
run into cases with /dev/zero?).

Thanks,
Richard.

> +     {
> +       /* If output is /dev/null or /dev/zero, we cannot set the dumpdir to
> +          /dev/ because no files can be created on that directory.  In this
> +          case, we do nothing.  */
> +     }
> +      else
> +     {
> +       /* Set dumpdir as being the same directory where the output file is.  
> */
> +       temp = lbasename (output_file);
> +       if (temp != output_file)
> +         dumpdir = xstrndup (output_file,
> +                             strlen (output_file) - strlen (temp));
> +     }
>      }
>    else if (dumpdir)
>      {
> diff --git a/gcc/testsuite/gcc.dg/devnull-dump.c 
> b/gcc/testsuite/gcc.dg/devnull-dump.c
> new file mode 100644
> index 00000000000..378e0901c28
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/devnull-dump.c
> @@ -0,0 +1,7 @@
> +/* { dg-do assemble } */
> +/* { dg-options "-fdump-ipa-clones -o /dev/null" } */
> +
> +int main()
> +{
> +  return 0;
> +}
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)

Reply via email to