llvm / llvm/llvm-project

[clang] Inconsistent attributes for dllexport __cxxabiv1:: __fundamental_type_info with -fvisibility=hidden

Open
#207,963 3 comments 0 reactions 0 assignees View on GitHub
clang
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Fundamentally, hidden visibility (`-fvisibility=hidden`) and dllexport are mutually exclusive. But in practice this is not an issue, dllexport is stronger and overrides `-fvisibility=hidden`.

```c++
void __declspec(dllexport) func(void) { }
void noexport(void) { }
```
```console
$ clang -target x86_64-windows-gnu -S -emit-llvm -o - export.cpp -fvisibility=hidden
[...]
define dso_local dllexport void @_Z4funcv() #0 {
entry:
ret void
}

[...]
define hidden void @_Z8noexportv() #0 {
entry:
ret void
}
```

If we explicitly try to specify the incompatible combination, we get an error:
```c++
void __declspec(dllexport) __attribute__((visibility("hidden"))) func(void) { }
```
```console
$ clang -target x86_64-windows-gnu -S -emit-llvm -o - export-hidden.cpp
export-hidden.cpp:1:66: error: hidden visibility cannot be applied to
'dllexport' declaration
1 | void __declspec(dllexport) __attribute__((visibility("hidden"))) func...
| ^
1 error generated.
```

However, for the type `__cxxabiv1:: __fundamental_type_info`, Clang implicitly generates symbols, where this can end up in a conflict:
```c++
namespace __cxxabiv1 {
struct
#ifdef EXPORT
__attribute__((dllexport))
#endif
__fundamental_type_info {
virtual ~__fundamental_type_info();
};
__fundamental_type_info::~__fundamental_type_info() {}
} // namespace __cxxabiv1
```
```console
$ clang -target x86_64-windows-gnu repro.cpp -fvisibility=hidden -c
$ clang -target x86_64-windows-gnu repro.cpp -fvisibility=hidden -c -DEXPORT
dllexport GlobalValue must have default or protected visibility
ptr @_ZTIv
dllexport GlobalValue must have default or protected visibility
ptr @_ZTSv
dllexport GlobalValue must have default or protected visibility
ptr @_ZTIPv
dllexport GlobalValue must have default or protected visibility
ptr @_ZTSPv
dllexport GlobalValue must have default or protected visibility
ptr @_ZTIPKv
dllexport GlobalValue must have default or protected visibility
ptr @_ZTSPKv
[...]
fatal error: error in backend: Broken module found, compilation aborted!
```

Contributor guide

Open the contributing guide

Research direction

Start by compiling the repro.cpp example with and without -DEXPORT using the two clang commands shown in the issue. Trace the implicitly generated __cxxabiv1:: fundamental_type_info symbols and how -fvisibility=hidden combines with dllexport. Done means the reproducer no longer produces a broken module or fatal backend error, with the intended visibility behavior preserved.

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
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.