[clang][Driver] Ensure intermediate bitcode files are written according to /Fo (#189977)

With the following compilation process:

```
$ mkdir -p src/ tmp/
$ cat << 'EOF' > src/main.c
int main() { return 0; }
EOF
$ clang-cl /c /Fo:tmp/ /clang:-fembed-bitcode src/main.c
```

the object file `main.obj` is generated in the `tmp/` directory but the
intermediate `main.bc` is placed in the current working directory.

This PR ensures that intermediate `.bc` files are written to the same
directory specified by `/Fo`.
This commit is contained in:
rthomas-activision 2026-04-09 18:40:43 +02:00 committed by GitHub
parent fa7f5cf6f6
commit 47c919a8b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 2 deletions

View file

@ -6576,7 +6576,9 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
// Determine what the derived output name should be.
const char *NamedOutput;
if ((JA.getType() == types::TY_Object || JA.getType() == types::TY_LTO_BC) &&
if ((JA.getType() == types::TY_Object || JA.getType() == types::TY_LTO_BC ||
JA.getType() == types::TY_LLVM_BC ||
JA.getType() == types::TY_LLVM_IR) &&
C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
// The /Fo or /o flag decides the object filename.
StringRef Val =
@ -6584,7 +6586,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
.getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
->getValue();
NamedOutput =
MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Object);
MakeCLOutputFilename(C.getArgs(), Val, BaseName, JA.getType());
} else if (JA.getType() == types::TY_Image &&
C.getArgs().hasArg(options::OPT__SLASH_Fe,
options::OPT__SLASH_o)) {

View file

@ -310,3 +310,19 @@
// RUN: %clang_cl -target x86_64-windows -fdebug-compilation-dir=. /Z7 /Fofoo/a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH2 %s
// RELATIVE_OBJPATH2: "-object-file-name=foo\\a.obj"
// RUN: %clang_cl /c /Fodir/ /clang:-fembed-bitcode -### -- %s 2>&1 | FileCheck -check-prefix=FoNAMEBC %s
// FoNAMEBC: "-o" "dir/cl-outputs.bc"
// FoNAMEBC: "-o" "dir/cl-outputs.obj"
// RUN: %clang_cl /c /clang:-emit-llvm -### -- %s 2>&1 | FileCheck -check-prefix=EMITLLVM %s
// EMITLLVM: "-o" "cl-outputs.bc"
// RUN: %clang_cl /c /Fodir/ /clang:-emit-llvm -### -- %s 2>&1 | FileCheck -check-prefix=EMITLLVM_Fo %s
// EMITLLVM_Fo: "-o" "dir/cl-outputs.bc"
// RUN: %clang_cl /c /odir/ /clang:-emit-llvm -### -- %s 2>&1 | FileCheck -check-prefix=EMITLLVM_o %s
// EMITLLVM_o: "-o" "dir/cl-outputs.bc"
// RUN: %clang_cl /c /omain.bc /clang:-emit-llvm -### -- %s 2>&1 | FileCheck -check-prefix=EMITLLVM_oNAME %s
// EMITLLVM_oNAME: "-o" "main.bc"