[clang] d8e9862 - [Driver] Gnu: Move -s/-t/-u emission to match GCC order (#192883)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 19 19:22:29 PDT 2026
Author: Fangrui Song
Date: 2026-04-20T02:22:24Z
New Revision: d8e9862e71b6bb7f5b8c06159429f31a1516299c
URL: https://github.com/llvm/llvm-project/commit/d8e9862e71b6bb7f5b8c06159429f31a1516299c
DIFF: https://github.com/llvm/llvm-project/commit/d8e9862e71b6bb7f5b8c06159429f31a1516299c.diff
LOG: [Driver] Gnu: Move -s/-t/-u emission to match GCC order (#192883)
GCC places -s, -t, and -u sym in one contiguous group just before
Scrt1.o / crt1.o, with -L paths after the CRT files.
Match that ordering by dropping the early `push_back("-s")` and rolling
-s, -t, and -u into one addAllArgs call placed immediately after -o
output. This keeps -Wl,... after -s/-t/-u so that user overrides like
-Wl,--strip-debug still take precedence. Update linux-ld-args.c to
-T remains at the end so earlier -L paths take precedence.
Added:
Modified:
clang/lib/Driver/ToolChains/Gnu.cpp
clang/test/Driver/linux-ld-args.c
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 2e7f78127a406..53cef4a934f4f 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -306,9 +306,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
- if (Args.hasArg(options::OPT_s))
- CmdArgs.push_back("-s");
-
if (Triple.isARM() || Triple.isThumb()) {
bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
if (IsBigEndian)
@@ -375,6 +372,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
+ Args.addAllArgs(CmdArgs, {options::OPT_s, options::OPT_t, options::OPT_u});
+
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
options::OPT_r)) {
if (!isAndroid && !IsIAMCU) {
@@ -435,7 +434,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Args.MakeArgString(ToolChain.GetFilePath("crt_pad_segment.o")));
}
- Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});
+ Args.addAllArgs(CmdArgs, {options::OPT_L});
ToolChain.AddFilePathLibArgs(Args, CmdArgs);
@@ -579,7 +578,10 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
}
- Args.addAllArgs(CmdArgs, {options::OPT_T, options::OPT_t});
+ // Emit -T after -L paths so that INPUT()/GROUP() directives in the linker
+ // script resolve against the user-supplied and toolchain search paths in GNU
+ // ld.
+ Args.addAllArgs(CmdArgs, {options::OPT_T});
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
C.addCommand(std::make_unique<Command>(JA, *this,
diff --git a/clang/test/Driver/linux-ld-args.c b/clang/test/Driver/linux-ld-args.c
index e047d6ce009e9..6ba21f6bc8a55 100644
--- a/clang/test/Driver/linux-ld-args.c
+++ b/clang/test/Driver/linux-ld-args.c
@@ -2,22 +2,26 @@
/// to the ld invocation. Sysroot-dependent toolchain discovery and
/// crt*/library-path selection live in linux-ld.c.
-/// Mixed -Xlinker, -Wl, and standalone forwarding. -T is reordered to the end
-/// so that earlier -L paths take precedence.
+/// Mixed -Xlinker, -Wl, and standalone forwarding. -t is emitted early near
+/// -s; -T is reordered to the end so that earlier -L paths take precedence.
// RUN: %clang --target=x86_64-linux-gnu -### \
// RUN: -e _start -T a.lds -t -Xlinker one -Xlinker --no-demangle \
// RUN: -Wl,two,--no-demangle,three -Xlinker four -z five -r %s 2>&1 | \
// RUN: FileCheck --check-prefix=MIXED %s
-// MIXED: "--no-demangle" "-e" "_start" "one" "two" "three" "four" "-z" "five" "-r" {{.*}} "-T" "a.lds" "-t"
+// MIXED: "-o" "a.out" "-t"
+// MIXED-SAME: "--no-demangle" "-e" "_start" "one" "two" "three" "four" "-z" "five" "-r"
+// MIXED-SAME: "-T" "a.lds"
/// Passthrough flags. -rdynamic becomes -export-dynamic; -Wl,-z keyword pairs
-/// are forwarded as separate "-z" KEYWORD tokens.
-// RUN: %clang --target=x86_64-linux-gnu -### \
+/// are forwarded as separate "-z" KEYWORD tokens. The -o/-s/-Wl, relative
+/// order mirrors gcc -###: -o output, -s, CRT-start, -L, then -Wl, forwarded
+/// args, so a later -Wl, can still override -s.
+// RUN: %clang --target=x86_64-linux-gnu -### -o a.out \
// RUN: -s -u my_sym -rdynamic -Wl,-z,relro,-z,now %s 2>&1 | \
// RUN: FileCheck --check-prefix=PASS %s
-// PASS: "-s"
-// PASS-SAME: "-export-dynamic"
-// PASS-SAME: "-u" "my_sym"
+// PASS: "-export-dynamic"
+// PASS-SAME: "-o" "a.out"
+// PASS-SAME: "-s" "-u" "my_sym"
// PASS-SAME: "-z" "relro" "-z" "now"
/// -nopie is OpenBSD-specific.
More information about the cfe-commits
mailing list