Index: libcxx/docs/DesignDocs/ABIVersioning.rst =================================================================== --- libcxx/docs/DesignDocs/ABIVersioning.rst +++ libcxx/docs/DesignDocs/ABIVersioning.rst @@ -22,3 +22,7 @@ ``_LIBCPP_ABI_VERSION``, which is controlled by the ``LIBCXX_ABI_VERSION`` set at build time. Libc++ does not intend users to interact with these C++ macros directly. + +The exception to this is MSVC environments. Libc++ does not currently have users +that require a stable ABI in MSVC environments, so MSVC-only changes may be +applied unconditionally. Index: libcxx/docs/index.rst =================================================================== --- libcxx/docs/index.rst +++ libcxx/docs/index.rst @@ -120,7 +120,7 @@ macOS 10.9+ i386, x86_64, arm64 Building the shared library itself requires targetting macOS 10.13+ FreeBSD 12+ i386, x86_64, arm Linux i386, x86_64, arm, arm64 Only glibc-2.24 and later and no other libc is officially supported -Windows i386, x86_64 Both MSVC and MinGW style environments +Windows i386, x86_64 Both MSVC and MinGW style environments, ABI in MSVC environments is unstable AIX 7.2TL5+ powerpc, powerpc64 =============== ========================= ============================ Index: libcxx/include/optional =================================================================== --- libcxx/include/optional +++ libcxx/include/optional @@ -638,7 +638,7 @@ template struct __is_std_optional> : true_type {}; template -class optional +class _LIBCPP_DECLSPEC_EMPTY_BASES optional : private __optional_move_assign_base<_Tp> , private __optional_sfinae_ctor_base_t<_Tp> , private __optional_sfinae_assign_base_t<_Tp> Index: libcxx/include/variant =================================================================== --- libcxx/include/variant +++ libcxx/include/variant @@ -1294,7 +1294,7 @@ } // namespace __variant_detail template -class _LIBCPP_TEMPLATE_VIS variant +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant : private __sfinae_ctor_base< __all...>::value, __all...>::value>, Index: libcxx/test/libcxx/utilities/optional/optional.object/optional_size.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/libcxx/utilities/optional/optional.object/optional_size.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// + +// template class optional; + +#include + +template +struct type_with_bool { + T value; + bool has_value; +}; + +int main(int, char**) { + // Test that std::optional achieves the expected size. See https://github.com/llvm/llvm-project/issues/61095. + static_assert(sizeof(std::optional) == sizeof(type_with_bool)); + static_assert(sizeof(std::optional) == sizeof(type_with_bool)); + static_assert(sizeof(std::optional) == sizeof(type_with_bool)); + static_assert(sizeof(std::optional) == sizeof(type_with_bool)); + + return 0; +} Index: libcxx/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp =================================================================== --- libcxx/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp +++ libcxx/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp @@ -60,6 +60,16 @@ static_assert(std::__variant_npos == IndexLim::max(), ""); } +template +struct type_with_index { + LargestType largest; +#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION + unsigned char index; +#else + unsigned int index; +#endif +}; + int main(int, char**) { test_index_type(); // This won't compile due to template depth issues. @@ -67,5 +77,12 @@ test_index_internals(); test_index_internals(); + // Test that std::variant achieves the expected size. See https://github.com/llvm/llvm-project/issues/61095. + static_assert(sizeof(std::variant) == sizeof(type_with_index)); + static_assert(sizeof(std::variant) == sizeof(type_with_index)); + static_assert(sizeof(std::variant) == sizeof(type_with_index)); + static_assert(sizeof(std::variant) == sizeof(type_with_index)); + static_assert(sizeof(std::variant) == sizeof(type_with_index)); + return 0; }