Haochen Jiang <[email protected]> writes:

> On Linux/x86_64,
>
> cc12934b555625b130e242eb6199c60b353ab509 is the first bad commit
> commit cc12934b555625b130e242eb6199c60b353ab509
> Author: Rainer Orth <[email protected]>
> Date:   Tue Feb 3 20:41:40 2026 +0100
>
>     build: Only use gas_flag/gnu_ld_flag internally [PR123841]
>
> caused
>
> FAIL: gcc.target/i386/pr118713-10.c scan-assembler call[ \t]*\\*%
> FAIL: gcc.target/i386/pr118713-10.c scan-assembler movl[ \t]*bar@GOT, 
> FAIL: gcc.target/i386/pr118713-11.c scan-assembler jmp[ \t]*\\*%
> FAIL: gcc.target/i386/pr118713-11.c scan-assembler movl[ \t]*bar@GOT, 
> FAIL: gcc.target/i386/pr118713-12.c scan-assembler call[ \t]*\\*%
> FAIL: gcc.target/i386/pr118713-12.c scan-assembler movl[ \t]*bar@GOT, 
> FAIL: gcc.target/i386/pr118713-9.c scan-assembler jmp[ \t]*\\*%
> FAIL: gcc.target/i386/pr118713-9.c scan-assembler movl[ \t]*bar@GOT, 

I've finally understood what's wrong: stupid mistake of mine.  If you
configure with GNU ld in path, but without giving --with-gnu-ld,
AC_ARG_WITH(gnu-ld) sets gnu_ld_flag to no, so the subsequent $gcc_cv_ld
--version check isn't even run, so gnu_ld_flag remains no even though
you *are* using GNU ld.  As a consequence, when e.g. the R_386_GOT32X
reloc check is run, the gcc_cv_ld $ld_32_opt invocation fails because
ld_32_opt hasn't been set at all, so the link test is run as

/usr/bin/ld -o conftest conftest.o

without -melf_i386 and fails.  Unfortunately, the output

ld: i386 architecture of input file `got32x.o' is incompatible with i386:x86-64 
output

is redirected to /dev/null, so this cannot be seen directly in config.log.

The solution is simple (as always): setting gnu_ld_flag must happen in
the ACTION_IF_NOT case of AC_ARG_WITH(gnu-ld), not afterwards.  Besides,
AC_ARG_WITH must be moved *after* gcc_cv_ld has been set.  And
gnu_ld_flag must be set *before* it is tested when setting ld_32_opt etc.

The same applies to gas_flag.

I'm testing the attached patch, which does just that.

This time I'm testing this like I should have before:

* On Linux/x86_64:

** with as/ld in PATH, no configure options

** with as/ld in PATH, --with-gnu-as --with-gnu-ld

** with --with-as=<path to as> --with-ld=<path to ld>

** with --with-as=<path to as> --with-ld=<path to ld> --with-gnu-as
   --with-gnu-ld

* On Solaris/i386:

** with Solaris as/ld in PATH, no configure options

** with Solaris as/ld in PATH, --without-gnu-as --without-gnu-ld

** with Solaris as/ld specified with --with-as=/usr/bin/as
   --with-ld=/usr/bin/ld

** with Solaris as/ld specified with --with-as=/usr/bin/as
   --with-ld=/usr/bin/ld --without-gnu-as --without-gnu-ld

** with GNU as/ld in PATH, no configure options

** with GNU as/ld in PATH, --with-gnu-as --with-gnu-ld

** with GNU as/ld specified with --with-as=/usr/gnu/bin/as
   --with-ld=/usr/gnu/bin/ld

** with GNU as/ld specified with --with-as=/usr/gnu/bin/as
   --with-ld=/usr/gnu/bin/ld --without-gnu-as --without-gnu-ld

I'm ignoring the nonsensical combinations here, e.g. using Solaris as
with --with-gnu-as or using GNU as with --without-gnu-as.

So far, auto-host.h is identical in all cases for

$ configure --disable-bootstrap && make configure-gcc

Let me run another round of testing before formally submitting this
patch.

Sorry again for all the mess I've created.

        Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2026-02-04  Rainer Orth  <[email protected]>

        gcc:
        * configure.ac (gnu_ld_flag): Move $gcc_cv_ld --version check into
        AC_ARG_WITH(gnu-ld).
        (gcc_cv_ld): Set before gnu_ld_flag.
        (gas_flag): Move $gcc_cv_ld --version check into AC_ARG_WITH(gnu-ld).
        (gcc_cv_as): Set before gas_flag.
        * configure: Regenerate.

# HG changeset patch
# Parent  8e3f8afff2a3f4f83ca592a5dd28f5f5c001e941
build: Properly set gcc_cv_as/gcc_cv_ld

diff --git a/gcc/configure b/gcc/configure
--- a/gcc/configure
+++ b/gcc/configure
@@ -969,11 +969,9 @@ with_gxx_include_dir
 with_gxx_libcxx_include_dir
 with_cpp_install_dir
 enable_generated_files_in_srcdir
-with_gnu_ld
 with_ld
 with_demangler_in_ld
 with_dsymutil
-with_gnu_as
 with_as
 with_windres
 enable_largefile
@@ -1011,6 +1009,7 @@ with_picolibc
 with_zstd
 with_zstd_include
 with_zstd_lib
+with_gnu_ld
 enable_rpath
 with_libiconv_prefix
 with_libiconv_type
@@ -1033,6 +1032,7 @@ enable_fast_install
 enable_libtool_lock
 enable_darwin_at_rpath
 with_darwin_extra_rpath
+with_gnu_as
 enable_ld
 enable_gold
 with_plugin_ld
@@ -1868,12 +1868,10 @@ Optional Packages:
   --with-cpp-install-dir=DIR
                           install the user visible C preprocessor in DIR
                           (relative to PREFIX) as well as PREFIX/bin
-  --with-gnu-ld           arrange to work with GNU ld
   --with-ld               arrange to use the specified ld (full pathname)
   --with-demangler-in-ld  try to use demangler in GNU ld
   --with-dsymutil         arrange to use the specified dsymutil (full
                           pathname)
-  --with-gnu-as           arrange to work with GNU as
   --with-as               arrange to use the specified as (full pathname)
   --with-windres          arrange to use the specified windres (full pathname)
   --with-stack-clash-protection-guard-size=size
@@ -1921,6 +1919,8 @@ Optional Packages:
   --with-darwin-extra-rpath=[ARG]
                           Specify a runpath directory, additional to those
                           provided by the compiler
+  --with-gnu-as           arrange to work with GNU as
+  --with-gnu-ld           arrange to work with GNU ld
   --with-plugin-ld=[ARG]  specify the plugin linker
   --with-glibc-version=M.N
                           assume GCC used with glibc version M.N or later
@@ -3925,16 +3925,6 @@ fi
 # Find default linker
 # -------------------
 
-# With GNU ld
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; gnu_ld_flag="$with_gnu_ld"
-else
-  gnu_ld_flag=no
-fi
-
-
 case $target in
     *darwin*)
 	ld64_flag=yes # Darwin can only use a ld64-compatible linker.
@@ -4031,16 +4021,6 @@ fi
 # Find default assembler
 # ----------------------
 
-# With GNU as
-
-# Check whether --with-gnu-as was given.
-if test "${with_gnu_as+set}" = set; then :
-  withval=$with_gnu_as; gas_flag="$with_gnu_as"
-else
-  gas_flag=no
-fi
-
-
 
 # Check whether --with-as was given.
 if test "${with_as+set}" = set; then :
@@ -21973,7 +21953,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 21976 "configure"
+#line 21956 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -22079,7 +22059,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 22082 "configure"
+#line 22062 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -25496,6 +25476,20 @@ fi
 fi
 fi
 
+# With GNU as
+
+# Check whether --with-gnu-as was given.
+if test "${with_gnu_as+set}" = set; then :
+  withval=$with_gnu_as; gas_flag="$with_gnu_as"
+else
+  if $gcc_cv_as --version 2>/dev/null | grep GNU > /dev/null; then
+   gas_flag=yes
+ else
+   gas_flag=no
+fi
+fi
+
+
 ORIGINAL_AS_FOR_TARGET=$gcc_cv_as
 
 case "$ORIGINAL_AS_FOR_TARGET" in
@@ -25504,15 +25498,6 @@ case "$ORIGINAL_AS_FOR_TARGET" in
  ;;
 esac
 
-# Check if we are using GNU as if not already set.
-if test -z "$gas_flag"; then
-  if $gcc_cv_as --version 2>/dev/null | grep GNU > /dev/null; then
-    gas_flag=yes
-  else
-    gas_flag=no
-  fi
-fi
-
 if $gcc_cv_as --help 2>&1 | grep -- --fatal-warnings > /dev/null; then
   fw_as_opt=--fatal-warnings
 fi
@@ -25626,6 +25611,20 @@ fi
 fi
 fi
 
+# With GNU ld
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; gnu_ld_flag="$with_gnu_ld"
+else
+  if $gcc_cv_ld --version 2>/dev/null | grep GNU > /dev/null; then
+   gnu_ld_flag=yes
+ else
+   gnu_ld_flag=no
+ fi
+fi
+
+
 ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
 PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
 # if the PLUGIN_LD is set ld-new, just have it as ld
@@ -25650,15 +25649,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-# Check if we are using GNU ld if not already set.
-if test -z "$gnu_ld_flag"; then
-  if $gcc_cv_ld --version 2>/dev/null | grep GNU > /dev/null; then
-    gnu_ld_flag=yes
-  else
-    gnu_ld_flag=no
-  fi
-fi
-
 case "$target:$gnu_ld_flag" in
   *-*-solaris2*:no)
     # While Solaris ld has -m32/-m64 it usually determines the ELF class
diff --git a/gcc/configure.ac b/gcc/configure.ac
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -332,12 +332,6 @@ AC_SUBST(GENINSRC)
 # Find default linker
 # -------------------
 
-# With GNU ld
-AC_ARG_WITH(gnu-ld,
-[AS_HELP_STRING([--with-gnu-ld], [arrange to work with GNU ld])],
-gnu_ld_flag="$with_gnu_ld",
-gnu_ld_flag=no)
-
 case $target in
     *darwin*)
 	ld64_flag=yes # Darwin can only use a ld64-compatible linker.
@@ -411,12 +405,6 @@ fi
 # Find default assembler
 # ----------------------
 
-# With GNU as
-AC_ARG_WITH(gnu-as,
-[AS_HELP_STRING([--with-gnu-as], [arrange to work with GNU as])],
-gas_flag="$with_gnu_as",
-gas_flag=no)
-
 AC_ARG_WITH(as,
 [AS_HELP_STRING([--with-as], [arrange to use the specified as (full pathname)])],
 DEFAULT_ASSEMBLER="$with_as")
@@ -2738,6 +2726,16 @@ else
         AC_PATH_PROG(gcc_cv_as, $AS_FOR_TARGET)
 fi])
 
+# With GNU as
+AC_ARG_WITH(gnu-as,
+[AS_HELP_STRING([--with-gnu-as], [arrange to work with GNU as])],
+gas_flag="$with_gnu_as",
+[if $gcc_cv_as --version 2>/dev/null | grep GNU > /dev/null; then
+   gas_flag=yes
+ else
+   gas_flag=no
+fi])
+
 ORIGINAL_AS_FOR_TARGET=$gcc_cv_as
 AC_SUBST(ORIGINAL_AS_FOR_TARGET)
 case "$ORIGINAL_AS_FOR_TARGET" in
@@ -2745,15 +2743,6 @@ case "$ORIGINAL_AS_FOR_TARGET" in
   *) AC_CONFIG_FILES(as:exec-tool.in, [chmod +x as]) ;;
 esac 
 
-# Check if we are using GNU as if not already set.
-if test -z "$gas_flag"; then
-  if $gcc_cv_as --version 2>/dev/null | grep GNU > /dev/null; then
-    gas_flag=yes
-  else
-    gas_flag=no
-  fi
-fi
-
 if $gcc_cv_as --help 2>&1 | grep -- --fatal-warnings > /dev/null; then
   fw_as_opt=--fatal-warnings
 fi
@@ -2820,6 +2809,16 @@ else
         AC_PATH_PROG(gcc_cv_ld, $LD_FOR_TARGET)
 fi])
 
+# With GNU ld
+AC_ARG_WITH(gnu-ld,
+[AS_HELP_STRING([--with-gnu-ld], [arrange to work with GNU ld])],
+gnu_ld_flag="$with_gnu_ld",
+[if $gcc_cv_ld --version 2>/dev/null | grep GNU > /dev/null; then
+   gnu_ld_flag=yes
+ else
+   gnu_ld_flag=no
+ fi])
+
 ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
 PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
 # if the PLUGIN_LD is set ld-new, just have it as ld
@@ -2837,15 +2836,6 @@ AC_ARG_WITH(plugin-ld,
 AC_SUBST(ORIGINAL_PLUGIN_LD_FOR_TARGET)
 AC_DEFINE_UNQUOTED(PLUGIN_LD_SUFFIX, "$PLUGIN_LD_SUFFIX", [Specify plugin linker])
 
-# Check if we are using GNU ld if not already set.
-if test -z "$gnu_ld_flag"; then
-  if $gcc_cv_ld --version 2>/dev/null | grep GNU > /dev/null; then
-    gnu_ld_flag=yes
-  else
-    gnu_ld_flag=no
-  fi
-fi
-
 case "$target:$gnu_ld_flag" in
   *-*-solaris2*:no)
     # While Solaris ld has -m32/-m64 it usually determines the ELF class

Reply via email to