On Windows, GCC is very likely to be installed in a directory
containing spaces. The patch from the original PR was used
downstream in MSYS2, while this patch provides a more general
way to fix the issue.
Currently, there is no dedicated test suite for specs. I have a
script for roughly checking the functionality of this part.
Bootstrapped and regtested on x86_64-linux-gnu and x86_64-w64-mingw32.
-- >8 --
do_spec_1() treats whitespace characters (' ' and '\t') as argument
terminators, causing splitting to occur. Therefore, we need to wrap
all spec functions whose return values should not be split
(e.g. file path) with the quote_spec() function. For example,
"dir with space/something.o" will be split into
"dir" "with" and "space/something.o".
pass_through_libs_spec_func() is somewhat special because the
multiple arguments it returns are expected to be split by ' ', but
each individual argument should not be split. Therefore, each
individual argument must be quoted first and then concatenated.
PR driver/90692
gcc/ChangeLog:
* gcc.cc (if_exists_spec_function): Escape special characters.
(if_exists_else_spec_function): Likewise.
(if_exists_then_else_spec_function): Likewise.
(version_compare_spec_function): Likewise.
(find_file_spec_function): Likewise.
(find_plugindir_spec_function): Likewise.
(pass_through_libs_spec_func): Likewise.
(find_fortran_preinclude_file): Likewise.
Signed-off-by: Wang Jinghao <[email protected]>
---
gcc/gcc.cc | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 43b0158ee02..82f1e23b500 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -10532,7 +10532,7 @@ if_exists_spec_function (int argc, const char **argv)
{
/* Must have only one argument. */
if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
- return argv[0];
+ return quote_spec (xstrdup (argv[0]));
return NULL;
}
@@ -10550,9 +10550,9 @@ if_exists_else_spec_function (int argc, const char
**argv)
return NULL;
if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
- return argv[0];
+ return quote_spec (xstrdup (argv[0]));
- return argv[1];
+ return quote_spec (xstrdup (argv[1]));
}
/* if-exists-then-else built-in spec function.
@@ -10570,10 +10570,10 @@ if_exists_then_else_spec_function (int argc, const
char **argv)
return NULL;
if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
- return argv[1];
+ return quote_spec (xstrdup (argv[1]));
if (argc == 3)
- return argv[2];
+ return quote_spec (xstrdup (argv[2]));
return NULL;
}
@@ -10771,7 +10771,7 @@ version_compare_spec_function (int argc, const char
**argv)
if (! result)
return NULL;
- return argv[nargs + 2];
+ return quote_spec (xstrdup (argv[nargs + 2]));
}
/* %:include builtin spec function. This differs from %include in that it
@@ -10805,7 +10805,7 @@ find_file_spec_function (int argc, const char **argv)
abort ();
file = find_file (argv[0]);
- return file;
+ return quote_spec (xstrdup (file));
}
@@ -10815,13 +10815,13 @@ find_file_spec_function (int argc, const char **argv)
static const char *
find_plugindir_spec_function (int argc, const char **argv ATTRIBUTE_UNUSED)
{
- const char *option;
+ char *option;
if (argc != 0)
abort ();
option = concat ("-iplugindir=", find_file ("plugin"), NULL);
- return option;
+ return quote_spec (option);
}
@@ -10999,13 +10999,17 @@ pass_through_libs_spec_func (int argc, const char
**argv)
break;
else if (!*lopt)
lopt = argv[n];
- prepended = concat (prepended, "-plugin-opt=-pass-through=-l",
- lopt, " ", NULL);
+ char *arg = concat ("-plugin-opt=-pass-through=-l", lopt, NULL);
+ arg = quote_spec (arg);
+ prepended = concat (prepended, arg, " ", NULL);
+ free (arg);
}
else if (!strcmp (".a", argv[n] + strlen (argv[n]) - 2))
{
- prepended = concat (prepended, "-plugin-opt=-pass-through=",
- argv[n], " ", NULL);
+ char *arg = concat ("-plugin-opt=-pass-through=", argv[n], NULL);
+ arg = quote_spec (arg);
+ prepended = concat (prepended, arg, " ", NULL);
+ free (arg);
}
if (prepended != old)
free (old);
@@ -11235,6 +11239,8 @@ find_fortran_preinclude_file (int argc, const char
**argv)
}
path_prefix_reset (&prefixes);
+ if (result)
+ result = quote_spec (result);
return result;
}
--
2.52.0