Skip to content

[libc++] Annotate the data member of variant with no_unique_address #137783

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libcxx/include/__configuration/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
// Use the smallest possible integer type to represent the index of the variant.
// Previously libc++ used "unsigned int" exclusively.
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
// Allow to reuse tail padding after the index of the variant with [[no_unique_address]] attribute.
# define _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
// Unstable attempt to provide a more optimized std::function
# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
// All the regex constants must be distinct and nonzero.
Expand Down
6 changes: 5 additions & 1 deletion libcxx/include/variant
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,11 @@ public:
# endif

private:
__variant_detail::__impl<_Types...> __impl_;
# ifdef _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
_LIBCPP_NO_UNIQUE_ADDRESS
# endif // _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
__variant_detail::__impl<_Types...>
__impl_;

friend struct __variant_detail::__access::__variant;
friend struct __variant_detail::__visitation::__variant;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ struct type_with_index {
#endif
};

struct alignas(16) A16 {};
struct VariantWithNoUniqueAddress {
TEST_NO_UNIQUE_ADDRESS std::variant<A16> a;
bool b;
};
struct VariantWithoutNoUniqueAddress {
std::variant<A16> a;
bool b;
};
constexpr bool ExpectSmallerSizeWithNoUniqueAddress =
#ifdef _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
true;
#else
false;
#endif

int main(int, char**) {
test_index_type<unsigned char>();
// This won't compile due to template depth issues.
Expand All @@ -84,5 +100,8 @@ int main(int, char**) {
static_assert(sizeof(std::variant<char, int, long>) == sizeof(type_with_index<long>));
static_assert(sizeof(std::variant<std::size_t, std::size_t, std::size_t>) == sizeof(type_with_index<std::size_t>));

static_assert((sizeof(VariantWithNoUniqueAddress) < sizeof(VariantWithoutNoUniqueAddress)) ==
ExpectSmallerSizeWithNoUniqueAddress);

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// REQUIRES: std-at-least-c++17

// <variant>

#include <cassert>
#include <variant>

#include "test_macros.h"

struct S {
TEST_NO_UNIQUE_ADDRESS std::variant<int, void*> a;
bool b;
};

TEST_CONSTEXPR_CXX20 bool test() {
S x{{}, true};
x.a.emplace<0>();
x.a.emplace<1>();
return x.b;
}

int main() {
assert(test());
#if TEST_STD_VER >= 20
static_assert(test());
#endif
}
Loading