[C++ Modules] False "definition with same mangled name as another definition" error for a static inline function reached via two different wrapper paths across two module interface units
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
### Description
Clang emits a spurious ODR-violation-style error (`definition with same mangled name '...' as another definition`) for a single `static inline` function defined in a header, when that header is textually included (via the global module fragment) into two different module interface units that both end up imported into the same translation unit — but only when the importing module reaches the function through a *different* call path than the imported module does.
There is exactly one definition of the function in the source. Clang appears to fail to merge/deduplicate the two textual copies of it pulled in through the two module BMIs, and instead treats them as conflicting definitions with the same mangled name.
### Environment
```
clang version 23.1.0 (https://github.com/llvm/llvm-project ea7d852a70e8bdfaf601d6626a760f9771b2c4b4)
Target: x86_64-pc-windows-msvc
```
### Minimal reproducer
**common.h**
```cpp
static inline void static_fn() {
}
inline void helper1() {
static_fn();
}
inline void helper2() {
static_fn();
}
```
**ModB.cppm**
```cpp
module;
#include "common.h"
export module ModB;
export inline void use_b() {
helper1();
}
```
**ModA.cppm**
```cpp
module;
#include "common.h"
export module ModA;
import ModB;
export inline void use_a() {
helper1();
helper2();
}
```
**main.cpp**
```cpp
import ModA;
int main() {
use_a();
}
```
### Build commands
```
clang++ -std=c++23 -fmodule-output=ModB.pcm -c ModB.cppm -o ModB.o
clang++ -std=c++23 -fmodule-output=ModA.pcm -fmodule-file=ModB=ModB.pcm -c ModA.cppm -o ModA.o
clang++ -std=c++23 -fmodule-file=ModA=ModA.pcm -fmodule-file=ModB=ModB.pcm -c main.cpp -o main.o
```
The first two invocations succeed with no diagnostics. The third fails with:
```
In module 'ModA' imported from main.cpp:1:
common.h:1:20: error: definition with same mangled name '?static_fn@@YAXXZ' as another definition
1 | static inline void static_fn() {
| ^
common.h:1:20: note: previous definition is here
1 | static inline void static_fn() {
| ^
1 error generated.
```
### Expected behavior
The build should succeed. `static_fn` has a single, identical definition; it is only reached multiple times because `ModA` and `ModB` each `#include "common.h"` in their global module fragments, and `ModA` also `import`s `ModB`. Sharing an internal header helper across module interface units this way should not trigger an ODR/mangled-name conflict.
Contributor guide
Research direction
Reproduce the diagnostic with common.h, ModA.cppm, ModB.cppm, and main.cpp using the three build commands, starting with the failing main.cpp compilation. Trace how the two module BMIs handle the duplicated static inline definition reached through different wrapper paths; done means the final command succeeds without the mangled-name conflict.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100