From f63e36870444dc3fa1aa49b878303304a8401076 Mon Sep 17 00:00:00 2001 From: Wang Jinghao Date: Wed, 1 Jul 2026 19:38:16 +0800 Subject: [PATCH] gcc: Replace the original patch with the new one that adds support for paths containing spaces in spec functions. The old patch disrupts the evaluation of spec functions. As a result, on MinGW targets, the expression used to add the default manifest file: `%:if-exists(default-manifest.o%s)` appends `default-manifest.o` to the end of the collect2 argument list regardless of whether the file actually exists. This is not the intended behavior. However, it usually does not cause an error on MSYS2 because the `mingw-w64-gcc` package depends on the `mingw-w64-windows-default-manifest` package. --- ...special-characters-in-spec-functions.patch | 141 ++++++++++++++++++ ...-spaces-in-path-for-default-manifest.patch | 60 -------- mingw-w64-gcc/PKGBUILD | 8 +- 3 files changed, 145 insertions(+), 64 deletions(-) create mode 100644 mingw-w64-gcc/0012-Escape-special-characters-in-spec-functions.patch delete mode 100644 mingw-w64-gcc/0012-Handle-spaces-in-path-for-default-manifest.patch diff --git a/mingw-w64-gcc/0012-Escape-special-characters-in-spec-functions.patch b/mingw-w64-gcc/0012-Escape-special-characters-in-spec-functions.patch new file mode 100644 index 0000000000000..dea123ee198de --- /dev/null +++ b/mingw-w64-gcc/0012-Escape-special-characters-in-spec-functions.patch @@ -0,0 +1,141 @@ +From 3b1c3f7d8ba4d8ee4690e8e109ee3bdbf0cef9cb Mon Sep 17 00:00:00 2001 +From: Wang Jinghao +Date: Wed, 27 May 2026 23:00:33 +0800 +Subject: [PATCH] driver: Escape special characters in spec functions [PR90692] + +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 +--- + 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 + diff --git a/mingw-w64-gcc/0012-Handle-spaces-in-path-for-default-manifest.patch b/mingw-w64-gcc/0012-Handle-spaces-in-path-for-default-manifest.patch deleted file mode 100644 index adc926b350381..0000000000000 --- a/mingw-w64-gcc/0012-Handle-spaces-in-path-for-default-manifest.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7bb1c4dfb29899729c13376cbae8393f201f1e83 Mon Sep 17 00:00:00 2001 -From: Olivier Michel -Date: Fri, 31 May 2019 15:07:06 +0200 -Subject: [PATCH 10/16] Handle spaces in path for default manifest - ---- - gcc/gcc.cc | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/gcc/gcc.cc b/gcc/gcc.cc -index afb23cd07b0..8eee9345afe 100644 ---- a/gcc/gcc.cc -+++ b/gcc/gcc.cc -@@ -6829,7 +6829,6 @@ eval_spec_function (const char *func, const char *args, - int save_arg_going; - int save_delete_this_arg; - int save_this_is_output_file; -- int save_this_is_library_file; - int save_input_from_pipe; - int save_this_is_linker_script; - const char *save_suffix_subst; -@@ -6847,7 +6846,6 @@ eval_spec_function (const char *func, const char *args, - save_arg_going = arg_going; - save_delete_this_arg = delete_this_arg; - save_this_is_output_file = this_is_output_file; -- save_this_is_library_file = this_is_library_file; - save_this_is_linker_script = this_is_linker_script; - save_input_from_pipe = input_from_pipe; - save_suffix_subst = suffix_subst; -@@ -6879,13 +6877,15 @@ eval_spec_function (const char *func, const char *args, - argbuf.address ()); - - /* Pop the spec processing context. */ -+ const char *saved_library_file = this_is_library_file ? argbuf.address()[0] : NULL; - argbuf.release (); - argbuf = save_argbuf; -+ if (saved_library_file) -+ argbuf.safe_push (saved_library_file); - - arg_going = save_arg_going; - delete_this_arg = save_delete_this_arg; - this_is_output_file = save_this_is_output_file; -- this_is_library_file = save_this_is_library_file; - this_is_linker_script = save_this_is_linker_script; - input_from_pipe = save_input_from_pipe; - suffix_subst = save_suffix_subst; -@@ -6957,8 +6957,9 @@ handle_spec_function (const char *p, bool *retval_nonnull, - /* p now points to just past the end of the spec function expression. */ - - funcval = eval_spec_function (func, args, soft_matched_part); -- if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0) -+ if (funcval != NULL && this_is_library_file == 0 && do_spec_1 (funcval, 0, NULL) < 0) - p = NULL; -+ - if (retval_nonnull) - *retval_nonnull = funcval != NULL; - --- -2.38.1 - diff --git a/mingw-w64-gcc/PKGBUILD b/mingw-w64-gcc/PKGBUILD index 1a21b0f60fa05..d8fd4b3ef7a73 100644 --- a/mingw-w64-gcc/PKGBUILD +++ b/mingw-w64-gcc/PKGBUILD @@ -53,7 +53,7 @@ else _url=https://gcc.gnu.org/pub/gcc/snapshots/${_version}-${_snapshot} fi _libdir=lib/gcc/${CHOST}/${pkgver} -pkgrel=5 +pkgrel=6 pkgdesc="GCC for the MinGW-w64" arch=('any') mingw_arch=('mingw32' 'mingw64' 'ucrt64') @@ -89,7 +89,7 @@ source=(${_url}/${_sourcedir}.tar.xz{,.sig} 0007-Build-EXTRA_GNATTOOLS-for-Ada.patch 0008-Prettify-linking-no-undefined.patch 0011-Enable-shared-gnat-implib.patch - 0012-Handle-spaces-in-path-for-default-manifest.patch + 0012-Escape-special-characters-in-spec-functions.patch 0014-gcc-9-branch-clone_function_name_1-Retain-any-stdcall-suffix.patch 0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch 0022-unset-native-system-header-dir.patch @@ -105,7 +105,7 @@ sha256sums=('50efb4d94c3397aff3b0d61a5abd748b4dd31d9d3f2ab7be05b171d36a510f79' '90d5cb570083f9dea4ac0f0f87e3e8d2230f5052e6f9b946061a20a224a9d195' '8d2d53ae26b777d90189240494de1b895c5efa1ebdcdfbf5774f29fc742499d9' '5ef4148acc4a2b7ed648d4fe75fab5545e84b4b93a12d6ba4e4ea6061dd635fa' - 'e98805ead7d78ee2a92f237894c4b2b7ddc1688e1b517d8c04f28d440202e40f' + 'd1bf7b3ffbb221efe5edae7e9cbf1147393b0920eb62d5f379f3dfa53bdd6e38' 'fd9bdecb2bbc4796bbc9f00b708dac42ef9e3464a06d6d27e5475cee117de5be' 'ad1f7b5e7afaaec008b7cbd14feea13a10989fa91bda7003af72d457619bb199' 'd8b9b979dc1742f63d23dfca92bc05944612bd196a31fb882b8a616baba84383' @@ -146,7 +146,7 @@ prepare() { 0007-Build-EXTRA_GNATTOOLS-for-Ada.patch \ 0008-Prettify-linking-no-undefined.patch \ 0011-Enable-shared-gnat-implib.patch \ - 0012-Handle-spaces-in-path-for-default-manifest.patch \ + 0012-Escape-special-characters-in-spec-functions.patch \ 0014-gcc-9-branch-clone_function_name_1-Retain-any-stdcall-suffix.patch \ 0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch \ 0022-unset-native-system-header-dir.patch