[clang] 837f998 - [clang-cl] Don't count linker inputs against /Fo and /Fa (#232611)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 20 19:46:42 PDT 2026
Author: Haohai Wen
Date: 2026-10-21T10:46:37+08:00
New Revision: 837f998d417a92ba9b56998e532454715749479f
URL: https://github.com/llvm/llvm-project/commit/837f998d417a92ba9b56998e532454715749479f
DIFF: https://github.com/llvm/llvm-project/commit/837f998d417a92ba9b56998e532454715749479f.diff
LOG: [clang-cl] Don't count linker inputs against /Fo and /Fa (#232611)
The /Fo and /Fa checks reject a file name when there is more than one
input. But the input list also holds object files, libraries, and linker
options such as -Xlinker, which go straight to the linker and never get
an output named by /Fo or /Fa. So
clang-cl /c foo.c /Fofoo.obj -Xlinker -bar
failed with "cannot specify '/Fofoo.obj' when compiling multiple source
files". MSVC's cl.exe also accepts .obj and .lib inputs next to
/Fo<file>.
Count only the inputs that get compiled.
Fixes #216085.
Added:
Modified:
clang/lib/Driver/Driver.cpp
clang/test/Driver/cl-outputs.c
Removed:
################################################################################
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 1c612c7d1547b..75471cfb63dd0 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -3387,27 +3387,25 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
const InputList &Inputs,
ActionList &Actions) const {
- // Diagnose misuse of /Fo.
- if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
- StringRef V = A->getValue();
- if (Inputs.size() > 1 && !V.empty() &&
- !llvm::sys::path::is_separator(V.back())) {
- // Check whether /Fo tries to name an output file for multiple inputs.
- Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
- << A->getSpelling() << V;
- Args.eraseArg(options::OPT__SLASH_Fo);
- }
- }
-
- // Diagnose misuse of /Fa.
- if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
- StringRef V = A->getValue();
- if (Inputs.size() > 1 && !V.empty() &&
- !llvm::sys::path::is_separator(V.back())) {
- // Check whether /Fa tries to name an asm file for multiple inputs.
- Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
- << A->getSpelling() << V;
- Args.eraseArg(options::OPT__SLASH_Fa);
+ // Diagnose misuse of /Fo and /Fa.
+ if (Arg *FoArg = Args.getLastArg(options::OPT__SLASH_Fo),
+ *FaArg = Args.getLastArg(options::OPT__SLASH_Fa);
+ FoArg || FaArg) {
+ // Linker inputs do not produce the outputs named by /Fo and /Fa.
+ unsigned NumCompiledInputs = llvm::count_if(
+ Inputs, [](const InputTy &I) { return I.first != types::TY_Object; });
+
+ for (Arg *A : {FoArg, FaArg}) {
+ if (!A)
+ continue;
+ StringRef V = A->getValue();
+ if (NumCompiledInputs > 1 && !V.empty() &&
+ !llvm::sys::path::is_separator(V.back())) {
+ // Check whether /Fo or /Fa names an output file for multiple inputs.
+ Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
+ << A->getSpelling() << V;
+ Args.eraseArg(A->getOption().getID());
+ }
}
}
diff --git a/clang/test/Driver/cl-outputs.c b/clang/test/Driver/cl-outputs.c
index c59adc8acb3b6..b480f62897214 100644
--- a/clang/test/Driver/cl-outputs.c
+++ b/clang/test/Driver/cl-outputs.c
@@ -37,6 +37,11 @@
// CHECK-MULTIPLESOURCEOK2: "-o" "cl-outputs.obj"
// CHECK-MULTIPLESOURCEOK2: "-o" "cl-outputs.obj"
+// RUN: %clang_cl /c /Foa.obj -Xlinker -foo -### -- %s foo.obj foo.lib 2>&1 | FileCheck -check-prefix=FoLINKERINPUT %s
+// RUN: %clang_cl /Foa.obj -Xlinker -foo -### -- %s foo.lib 2>&1 | FileCheck -check-prefix=FoLINKERINPUT %s
+// FoLINKERINPUT-NOT: error: cannot specify '/Foa.obj' when compiling multiple source files
+// FoLINKERINPUT: "-o" "a.obj"
+
// RUN: %clang_cl /c /oa -### -- %s 2>&1 | FileCheck -check-prefix=oNAME1 %s
// oNAME1: "-o" "a.obj"
@@ -243,6 +248,9 @@
// RUN: %clang_cl /Fa -### -- %s %s 2>&1 | FileCheck -check-prefix=FaMULTIPLESOURCEOK %s
// FaMULTIPLESOURCEOK: "-o" "cl-outputs.asm"
// FaMULTIPLESOURCEOK: "-o" "cl-outputs.asm"
+// RUN: %clang_cl /Faa.asm -Xlinker -foo -### -- %s foo.obj 2>&1 | FileCheck -check-prefix=FaLINKERINPUT %s
+// FaLINKERINPUT-NOT: error: cannot specify '/Faa.asm' when compiling multiple source files
+// FaLINKERINPUT: "-o" "a.asm"
// Copy of the same tests above, but with /FAcsu
// RUN: %clang_cl /FAcsu -### -- %s 2>&1 | FileCheck -check-prefix=FA_CSU %s
More information about the cfe-commits
mailing list