llvm / llvm/llvm-project

[clang-cl] `/Fo` check incorrectly treats `-Xlinker ...` as an input

Open
#216,085 1 comment 0 reactions 0 assignees View on GitHub
clang-cl clang:driver
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.