Skip to content

[libc++] ABI break between Clang 15 and Clang 16 for some trivially copiable pairs in C++ >= 23 #95428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ldionne opened this issue Jun 13, 2024 · 1 comment · Fixed by #95444
Assignees
Labels
ABI Application Binary Interface libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Comments

@ldionne
Copy link
Member

ldionne commented Jun 13, 2024

#include <type_traits>
#include <utility>

struct trivially_copyable_no_assignment {
  int arr[4];
  trivially_copyable_no_assignment& operator=(const trivially_copyable_no_assignment&) = delete;
};

static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_assignment, int> >::value, "");

int main() { }

is_trivially_copyable was true on Clang 15 and became false on Clang 16 and above. This only affects C++23 and C++26, which also means that we now have a different ABI between C++20 and C++23 in recent Clangs.

Godbolt: https://godbolt.org/z/hEWq59oeP

@ldionne ldionne added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. ABI Application Binary Interface labels Jun 13, 2024
@ldionne
Copy link
Member Author

ldionne commented Jun 13, 2024

According to the thread in #89652 (comment), this probably bisects to 83ead2b.

@ldionne ldionne self-assigned this Jun 13, 2024
ldionne added a commit to ldionne/llvm-project that referenced this issue Jun 13, 2024
…hout an assignment operator

Since 83ead2b, std::pair would not be trivially copyable when it holds
a trivially copyable type without an assignment operator. That is because
pair gained an elligible copy-assignment-operator (the const version) in
83ead2b in C++ >= 23.

This means that the trivially copyable property of std::pair for such
types would be inconsistent between C++11/14/17/20 (trivially copyable)
and C++23/26 (not trivially copyable). This patch makes std::pair's
behavior consistent in all Standard modes EXCEPT C++03, which is a
pre-existing condition and we have no way of changing (also, it shouldn't
matter because the std::is_trivially_copyable trait was introduced in
C++11).

While this is not technically an ABI break, in practice we do know that
folks sometimes use a different representation based on whether a type
is trivially copyable. So we're treating 83ead2b as an ABI break and
this patch is fixing said breakage.

This patch also adds tests stolen from llvm#89652 that pin down the ABI
of std::pair with respect to being trivially copyable.

Fixes llvm#95428
ldionne added a commit to ldionne/llvm-project that referenced this issue Jun 17, 2024
…hout an assignment operator

Since 83ead2b, std::pair would not be trivially copyable when it holds
a trivially copyable type without an assignment operator. That is because
pair gained an elligible copy-assignment-operator (the const version) in
83ead2b in C++ >= 23.

This means that the trivially copyable property of std::pair for such
types would be inconsistent between C++11/14/17/20 (trivially copyable)
and C++23/26 (not trivially copyable). This patch makes std::pair's
behavior consistent in all Standard modes EXCEPT C++03, which is a
pre-existing condition and we have no way of changing (also, it shouldn't
matter because the std::is_trivially_copyable trait was introduced in
C++11).

While this is not technically an ABI break, in practice we do know that
folks sometimes use a different representation based on whether a type
is trivially copyable. So we're treating 83ead2b as an ABI break and
this patch is fixing said breakage.

This patch also adds tests stolen from llvm#89652 that pin down the ABI
of std::pair with respect to being trivially copyable.

Fixes llvm#95428
ldionne added a commit to ldionne/llvm-project that referenced this issue Jun 17, 2024
…hout an assignment operator

Since 83ead2b, std::pair would not be trivially copyable when it holds
a trivially copyable type without an assignment operator. That is because
pair gained an elligible copy-assignment-operator (the const version) in
83ead2b in C++ >= 23.

This means that the trivially copyable property of std::pair for such
types would be inconsistent between C++11/14/17/20 (trivially copyable)
and C++23/26 (not trivially copyable). This patch makes std::pair's
behavior consistent in all Standard modes EXCEPT C++03, which is a
pre-existing condition and we have no way of changing (also, it shouldn't
matter because the std::is_trivially_copyable trait was introduced in
C++11).

While this is not technically an ABI break, in practice we do know that
folks sometimes use a different representation based on whether a type
is trivially copyable. So we're treating 83ead2b as an ABI break and
this patch is fixing said breakage.

This patch also adds tests stolen from llvm#89652 that pin down the ABI
of std::pair with respect to being trivially copyable.

Fixes llvm#95428
ldionne added a commit to ldionne/llvm-project that referenced this issue Jun 18, 2024
…hout an assignment operator

Since 83ead2b, std::pair would not be trivially copyable when it holds
a trivially copyable type without an assignment operator. That is because
pair gained an elligible copy-assignment-operator (the const version) in
83ead2b in C++ >= 23.

This means that the trivially copyable property of std::pair for such
types would be inconsistent between C++11/14/17/20 (trivially copyable)
and C++23/26 (not trivially copyable). This patch makes std::pair's
behavior consistent in all Standard modes EXCEPT C++03, which is a
pre-existing condition and we have no way of changing (also, it shouldn't
matter because the std::is_trivially_copyable trait was introduced in
C++11).

While this is not technically an ABI break, in practice we do know that
folks sometimes use a different representation based on whether a type
is trivially copyable. So we're treating 83ead2b as an ABI break and
this patch is fixing said breakage.

This patch also adds tests stolen from llvm#89652 that pin down the ABI
of std::pair with respect to being trivially copyable.

Fixes llvm#95428
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this issue Jul 9, 2024
…hout an assignment operator (llvm#95444)

Since 83ead2b, std::pair would not be trivially copyable when it holds a
trivially copyable type without an assignment operator. That is because
pair gained an elligible copy-assignment-operator (the const version) in
83ead2b in C++ >= 23.

This means that the trivially copyable property of std::pair for such
types would be inconsistent between C++11/14/17/20 (trivially copyable)
and C++23/26 (not trivially copyable). This patch makes std::pair's
behavior consistent in all Standard modes EXCEPT C++03, which is a
pre-existing condition and we have no way of changing (also, it
shouldn't matter because the std::is_trivially_copyable trait was
introduced in C++11).

While this is not technically an ABI break, in practice we do know that
folks sometimes use a different representation based on whether a type
is trivially copyable. So we're treating 83ead2b as an ABI break and
this patch is fixing said breakage.

This patch also adds tests stolen from llvm#89652 that pin down the ABI of
std::pair with respect to being trivially copyable.

Fixes llvm#95428
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ABI Application Binary Interface libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
1 participant