Issue |
120108
|
Summary |
[clang][modules] Inline function incorrectly marked as hidden leads to undefined reference
|
Labels |
clang,
clang:modules
|
Assignees |
|
Reporter |
ldionne
|
In some circumstances, functions are incorrectly given hidden visibility when Clang modules are enabled, which leads to undefined references. Here's a reproducer where we basically have two small header files, each of which is a module:
```c++
// construct_at:
template <class T>
constexpr void __construct_at(T* location, T arg) {
void* loc = __voidify(*location);
(void)loc;
}
```
```c++
// voidify
template <class T>
__attribute__((__always_inline__)) void* __voidify(T& from) {
return const_cast<void*>(static_cast<const volatile void*>(&from));
}
```
We then have a small test program that uses `construct_at`:
```c++
#include <construct_at.h>
void foo(int* ptr) {
__construct_at(ptr, 3);
}
```
Finally, we compile with modules enabled:
```
clang++ -std=c++17 -fmodules -fcxx-modules -fmodules-cache-path=ModuleCache.noindex -fbuiltin-module-map -c test.cpp -o test.o
```
And we can see that an undefined reference to `__voidify` is being generated in `test.o`, which should never happen for a few reasons:
1. It's a template, so we need to have a `linkonce_odr` definition in `test.o`
2. Even worse, it's marked as `always_inline` so it's absolutely evident that this can't end happily. Indeed, we know at the declaration that a definition will never be emitted anywhere else, so this is bound to fail.
In other words, this shouldn't create an undefined reference to `__voidify` regardless of whether that function is marked as `__always_inline__`, but it's just a bit more vexing that it does.
[Full reproducer](https://github.com/user-attachments/files/18153807/reproducer.zip) attached.
Also tracked as rdar://121551667.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs