Skip to content

[libc++] Vendor communication: upcoming ABI breaks in std::expected and parts of <ranges> #70820

Closed
@ldionne

Description

@ldionne

Hi @llvm/libcxx-vendors,

This issue is not a traditional issue. It is a communication to vendors about upcoming ABI breaks in std::expected and some parts of <ranges>. It was recently brought to our attention in #70494 (see the associated PR for more discussion) that there is a problem with some of the library's usage of [[no_unique_address]], which can lead to objects overlapping with padding bytes of other objects and their contents being overwritten unexpectedly.

We are aware of this issue in std::expected and in std::__movable_box, which is used to implement several views in <ranges>. Fixing this will require breaking the ABI for the types involved. We introduced std::expected and __movable_box in LLVM 16 so this has been shipping for two releases. We are aiming to fix these issues in LLVM 18.

Typically, we do not expect code to expose a lot of <ranges> views at ABI boundaries, so we believe the __movable_box ABI break to have a limited fallout. However, std::expected is a vocabulary type and is intended to appear at all kinds of API (and ABI) boundaries, in particular function result types. That ABI break is more likely to cause actual issues in the wild.

At this moment, we want to make vendors aware of these upcoming changes so they can plan ahead and perhaps limit the blast radius in case they haven't shipped LLVM 16/17 yet. One possibility would be to disable std::expected in their downstream release or keep it experimental behind -fexperimental-library. We will update this thread as we gain more clarity on the exact nature of the upcoming ABI break (e.g. which types are impacted and under what circumstances).

FAQ

Q: Are you going to allow vendors to opt into the old/new ABI for these types?
A: No. The current ABI has correctness issues which are serious enough that nobody should opt into the old ABI. This isn't a performance improvement or a slight conformance fix.

Q: Are you going to take this opportunity to enable other ABI breaks, effectively moving to "ABI v2"?
A: No. The intent of these changes is to keep the ABI break as narrow as possible with the hopes that the actual fallout will be limited. <ranges> is seldom used at ABI boundaries. std::expected shipped only recently, requires C++23 and we expect that few users will have had the time to depend on it in their ABI.

Q: Is it possible to use some techniques to try and diagnose when folks have an ABI mismatch after shipping that ABI break?
A: Yes, to some extent. We will use ABI tags to influence the mangling of functions that contain a type that undergoes an ABI break. This means that trying to link two units using/providing a function whose signature contains e.g. std::expected will fail at link time since the mangled name of the function will be different between LLVM 17 and LLVM 18. However, this technique has limitations. For example, if a std::expected is contained in a user-defined class, the user-defined class will not get an ABI tag despite its layout potentially changing between LLVM 17 and LLVM 18.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ABIApplication Binary Interfacelibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions