[libcxx-commits] [libcxx] [libc++] Introduce ABI sensitive areas to avoid requiring _LIBCPP_HIDE_FROM_ABI everywhere (PR #131156)
James Y Knight via libcxx-commits
libcxx-commits at lists.llvm.org
Tue May 27 08:29:02 PDT 2025
jyknight wrote:
I believe this change does need to be reverted, unfortunately. I would submit that we are, in effect, "rejecting valid code" now.
User code, without shared libraries in the picture, may write in a header `a.h`
```
#include <functional>
struct UserType {};
namespace std {
template<> struct hash<UserType> {
size_t operator()(const UserType&) const;
};
}
```
and then define that function in one TU, `a.cc`, and call it from another TU `b.cc`. That is uncontroversially standard expected behavior.
The next question is: what if `a.cc` and `b.cc` are built into two different shared libraries? I acknowledge that the standard does not say anything whatsoever about shared libraries and how they work. However, on ELF platforms, the answer to this question is absolutely clear: by default, shared libraries work "transparently". That is, they shouldn't break any of the standard-proscribed behaviors you'd expect to have _without_ shared libraries in the picture.
Users can of course do many things to _explicitly_ break this default expectation (such as adding symbol visibility attributes, linker scripts with symbol visibility lists, etc etc.). Yet, without any of that, everything should work the same as you'd get in a program without shared libraries in play. This is a long-standing expectation (on ELF platforms), and many things depend on it.
This change, unfortunately, breaks that expectation, by causing the definition of this user-defined function to be marked hidden -- without the user code having any such non-standard attributes or linker/compiler flags.
> @dschuff AFAICT this only affects cases where you specialize a class from the std namespace and want to export a symbol from that class, but don't have explicit visibility markups. I just don't see how that's a common occurrence. (FWIW I also don't see how the different usage pattern makes it fine to export a bunch of symbols. Symbols visibility affects way more than just whether a symbol is actually exported.)
Defining custom specializations of std classes is common. Building shared libraries without using any symbol visibility attributes, and expecting the default behaviors is also common. Neither are a weird edge case.
https://github.com/llvm/llvm-project/pull/131156
More information about the libcxx-commits
mailing list