[PATCH] D147832: [libcxx] Introduce clang::lto_visibility_public attribute

Louis Dionne via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 12 06:31:24 PDT 2023


ldionne added a comment.

In D147832#4256529 <https://reviews.llvm.org/D147832#4256529>, @leonardchan wrote:

>> You say you build with -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -fvisibility=hidden which AFAICT defeats the purpose of a shared library, since it wouldn't export a single symbol.
>
> My bad, I should've clarified on this. For fuchsia, we build everything with hidden visibility by default and individual binaries need to explicitly mark their symbols with default visibility if they want to be exported. This also means that when a fuchsia binary uses libc++, we need to make sure it doesn't accidentally export any libc++ symbols. Fuchsia binaries can consume libc++ as either a shared lib or a hermetic static lib, but we don't know at compile time how libc++ will eventually be consumed. If used as a shared lib, then symbols will be defined libc++.so. If linked in as a hermetic static lib, then we need to ensure those symbols have hidden visibility. To cover both cases and prevent us from having to compile twice, we just compile everything with `-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -fvisibility=hidden`.

I still don't understand your setup. So you compile the program using LTO and passing `-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -fvisibility=hidden`, right? That way the program itself doesn't export any libc++ symbols and everything in the program has hidden visibility AND hidden LTO visibility. But then you compile `libc++.so` with `-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -fvisibility=hidden`, which causes everything in `libc++.so` to have hidden visibility. But since you compile `libc++.so` with LTO disabled, everything in `libc++.so` has default LTO visibility.

So for example, let's say you have a `std::map<int, int>` instantiated in your program and let's say there's also one instantiated inside `libc++.so`. On the program side, `std::map<int, int>` has hidden visibility because you passed `-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -fvisibility=hidden`, and it has hidden LTO visibility for the same reason. On the `libc++.so` side, it has hidden visibility because you passed `-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -fvisibility=hidden` when building the `.so`, but it has default LTO visibility because you did not compile `libc++.so` with LTO enabled. That's an ODR violation. Is that correct?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147832/new/

https://reviews.llvm.org/D147832



More information about the llvm-commits mailing list