[clang-cl] `/Fo` check incorrectly treats `-Xlinker ...` as an input
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
### Reproducer
```console
E:\sandbox
❯ pixi exec -w clang=22.* nu
E:\sandbox via v22.1.8-clang via 🧚 v0.76.2 (temp:clang)
❯ clang-cl.exe /Fofoo bar.c /link baz
LINK : fatal error LNK1181: cannot open input file 'baz.obj'
clang-cl: error: linker command failed with exit code 1181 (use -v to see invocation)
E:\sandbox via v22.1.8-clang via 🧚 v0.76.2 (temp:clang)
❯ clang-cl.exe /Fofoo bar.c -Xlinker baz
clang-cl: error: cannot specify '/Fofoo' when compiling multiple source files
```
### Bug explanation
`clang-cl` has a check that when `/Fo...` is used to name an output file, only a single input is present: https://github.com/llvm/llvm-project/blob/6748b368cdd443a2539b94452e2da6a46219721c/clang/lib/Driver/Driver.cpp#L4349-L4359
`clang-cl.exe /Fofoo bar.c -Xlinker baz` erroneously fails this check -- it seems `-Xlinker baz` is treated as an 'input', meaning that `Inputs.size() > 1`.
`clang-cl.exe /Fofoo bar.c /link baz` does not fail this check -- it seems `/link baz` is not treated as an input, and we get the expected error from the linker instead.
### Cause
https://github.com/llvm/llvm-project/blob/6748b368cdd443a2539b94452e2da6a46219721c/clang/include/clang/Options/Options.td#L1095-L1098
https://github.com/llvm/llvm-project/blob/6748b368cdd443a2539b94452e2da6a46219721c/clang/lib/Driver/Driver.cpp#L3321-L3324
This seems to be where it is decided that `-Xlinker ...` will be added to inputs.
Perhaps the comment there hints at a solution -- rather than just being treated as object type, we could have a new type which is explicitly ignored in the `/Fo` misuse check?
### Comments
Apparently `-o` does not hit this problem, because there effort is put in to figure out the `NumOutputs` for the inputs: https://github.com/llvm/llvm-project/blob/6748b368cdd443a2539b94452e2da6a46219721c/clang/lib/Driver/Driver.cpp#L5535-L5541
Contributor guide
Research direction
Start in clang/lib/Driver/Driver.cpp around the /Fo misuse check and input classification, then inspect clang/include/clang/Options/Options.td around the -Xlinker definition. Reproduce with the clang-cl.exe commands in the issue and add regression coverage showing that -Xlinker does not trigger the /Fo check while the expected linker behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- cli, compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100