[libcxx-commits] [libcxx] 42f5277 - [libc++] Fix __datasizeof_v for Clang17 and 18 in C++03 (#106832)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Sep 3 10:46:12 PDT 2024


Author: Nikolas Klauser
Date: 2024-09-03T19:46:08+02:00
New Revision: 42f5277de16cd7fad01285ade9004675b8253ced

URL: https://github.com/llvm/llvm-project/commit/42f5277de16cd7fad01285ade9004675b8253ced
DIFF: https://github.com/llvm/llvm-project/commit/42f5277de16cd7fad01285ade9004675b8253ced.diff

LOG: [libc++] Fix __datasizeof_v for Clang17 and 18 in C++03 (#106832)

This also disables the use of `__datasizeof`, since it's currently
broken for empty types.

Added: 
    

Modified: 
    libcxx/include/__config
    libcxx/include/__type_traits/datasizeof.h
    libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__config b/libcxx/include/__config
index b8ec905a5cbfa6..bccf90d1dbacd2 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -997,21 +997,9 @@ typedef __char32_t char32_t;
 // (If/when MSVC breaks its C++ ABI, it will be changed to work as intended.)
 // However, MSVC implements [[msvc::no_unique_address]] which does what
 // [[no_unique_address]] is supposed to do, in general.
-
-// Clang-cl does not yet (14.0) implement either [[no_unique_address]] or
-// [[msvc::no_unique_address]] though. If/when it does implement
-// [[msvc::no_unique_address]], this should be preferred though.
 #    define _LIBCPP_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
-#  elif __has_cpp_attribute(no_unique_address)
-#    define _LIBCPP_NO_UNIQUE_ADDRESS [[__no_unique_address__]]
 #  else
-#    define _LIBCPP_NO_UNIQUE_ADDRESS /* nothing */
-// Note that this can be replaced by #error as soon as clang-cl
-// implements msvc::no_unique_address, since there should be no C++20
-// compiler that doesn't support one of the two attributes at that point.
-// We generally don't want to use this macro outside of C++20-only code,
-// because using it conditionally in one language version only would make
-// the ABI inconsistent.
+#    define _LIBCPP_NO_UNIQUE_ADDRESS [[__no_unique_address__]]
 #  endif
 
 // c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these

diff  --git a/libcxx/include/__type_traits/datasizeof.h b/libcxx/include/__type_traits/datasizeof.h
index 35c12921e8ffa1..b4cbd1ddfa8deb 100644
--- a/libcxx/include/__type_traits/datasizeof.h
+++ b/libcxx/include/__type_traits/datasizeof.h
@@ -26,34 +26,22 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_keyword(__datasizeof) || __has_extension(datasizeof)
+// TODO: Enable this again once #94816 is fixed.
+#if (__has_keyword(__datasizeof) || __has_extension(datasizeof)) && 0
 template <class _Tp>
 inline const size_t __datasizeof_v = __datasizeof(_Tp);
 #else
-// NOLINTNEXTLINE(readability-redundant-preprocessor) This is https://llvm.org/PR64825
-#  if __has_cpp_attribute(__no_unique_address__)
 template <class _Tp>
 struct _FirstPaddingByte {
-  [[__no_unique_address__]] _Tp __v_;
+  _LIBCPP_NO_UNIQUE_ADDRESS _Tp __v_;
   char __first_padding_byte_;
 };
-#  else
-template <class _Tp, bool = __libcpp_is_final<_Tp>::value || !is_class<_Tp>::value>
-struct _FirstPaddingByte : _Tp {
-  char __first_padding_byte_;
-};
-
-template <class _Tp>
-struct _FirstPaddingByte<_Tp, true> {
-  _Tp __v_;
-  char __first_padding_byte_;
-};
-#  endif // __has_cpp_attribute(__no_unique_address__)
 
 // _FirstPaddingByte<> is sometimes non-standard layout. Using `offsetof` is UB in that case, but GCC and Clang allow
 // the use as an extension.
 _LIBCPP_DIAGNOSTIC_PUSH
 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-offsetof")
+_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Winvalid-offsetof")
 template <class _Tp>
 inline const size_t __datasizeof_v = offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_);
 _LIBCPP_DIAGNOSTIC_POP

diff  --git a/libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp b/libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp
index 03dd0f6eac53a2..90463b0ac06e43 100644
--- a/libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp
+++ b/libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp
@@ -8,13 +8,25 @@
 
 #include <__type_traits/datasizeof.h>
 #include <cstdint>
+#include <type_traits>
 
 static_assert(std::__datasizeof_v<std::int8_t> == 1, "");
 static_assert(std::__datasizeof_v<std::int16_t> == 2, "");
 static_assert(std::__datasizeof_v<std::int32_t> == 4, "");
 static_assert(std::__datasizeof_v<std::int64_t> == 8, "");
 
-struct OneBytePadding {
+struct NonStandardLayout {
+  virtual ~NonStandardLayout();
+};
+
+static_assert(!std::is_standard_layout<NonStandardLayout>::value, "");
+static_assert(std::__datasizeof_v<NonStandardLayout> == sizeof(void*), "");
+
+struct Empty {};
+
+static_assert(std::__datasizeof_v<Empty> == 0, "");
+
+struct OneBytePadding final {
   OneBytePadding() {}
 
   std::int16_t a;
@@ -36,3 +48,9 @@ struct InBetweenPadding {
 };
 
 static_assert(std::__datasizeof_v<InBetweenPadding> == 8, "");
+
+struct NoDataButNoPadding {
+  OneBytePadding v;
+};
+
+static_assert(std::__datasizeof_v<NoDataButNoPadding> == 4, "");


        


More information about the libcxx-commits mailing list