From 52a49f9e480ca03e231cfda82640a928393131c9 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Mon, 21 Sep 2020 21:01:40 +0200 Subject: static_assert that O[U]StringLiteral are layout compatible with rtl_[u]String ...as was suggested by Mike Kaganski in a comment at "Turn OUStringLiteral into a consteval'ed, static-refcound rtl_uString". Doing so revealed that at least lopglugin:unusedmember needs to handle InjectedClassNameType as an alternative to RecordType in at least one place. (More places across compilerplugins might benefit from handling InjectedClassNameType too, but which did not lead to assertion failures for now and should be addressed in follow-up issues.) Change-Id: Icdb8b069324b5ce5f3c7c6b92989379ccb67fc8b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103125 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- include/rtl/string.hxx | 21 +++++++++++++++++++++ include/rtl/ustring.hxx | 20 ++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'include') diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx index 7086de15c987..fd65e2dfa477 100644 --- a/include/rtl/string.hxx +++ b/include/rtl/string.hxx @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #if defined LIBO_INTERNAL_ONLY #include +#include #endif #include "rtl/textenc.h" @@ -114,12 +116,31 @@ public: constexpr char const * getStr() const SAL_RETURNS_NONNULL { return buffer; } + // offsetof needs a complete type, so do not have these static_asserts as class template + // members, but postpone their instantiation to the later non-member static_assert that calls + // detail_assertLayout: + static constexpr bool detail_assertLayout() { + static_assert(offsetof(OStringLiteral, refCount) == offsetof(rtl_String, refCount)); + static_assert( + std::is_same_v); + static_assert(offsetof(OStringLiteral, length) == offsetof(rtl_String, length)); + static_assert(std::is_same_v); + static_assert(offsetof(OStringLiteral, buffer) == offsetof(rtl_String, buffer)); + static_assert( + std::is_same_v< + std::remove_extent_t, + std::remove_extent_t>); + return true; + } + private: // Same layout as rtl_String (include/rtl/string.h): oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx) sal_Int32 length = N - 1; char buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) }; + +static_assert(OStringLiteral<1>::detail_assertLayout()); #endif /* ======================================================================= */ diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index 45272b325cc0..f458ac061ea4 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #if defined LIBO_INTERNAL_ONLY #include +#include #endif #include "rtl/ustring.h" @@ -98,6 +100,22 @@ public: constexpr operator std::u16string_view() const { return {buffer, sal_uInt32(length)}; } + // offsetof needs a complete type, so do not have these static_asserts as class template + // members, but postpone their instantiation to the later non-member static_assert that calls + // detail_assertLayout: + static constexpr bool detail_assertLayout() { + static_assert(offsetof(OUStringLiteral, refCount) == offsetof(rtl_uString, refCount)); + static_assert(std::is_same_v); + static_assert(offsetof(OUStringLiteral, length) == offsetof(rtl_uString, length)); + static_assert(std::is_same_v); + static_assert(offsetof(OUStringLiteral, buffer) == offsetof(rtl_uString, buffer)); + static_assert( + std::is_same_v< + std::remove_extent_t, + std::remove_extent_t>); + return true; + } + private: // Same layout as rtl_uString (include/rtl/ustring.h): oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx) @@ -105,6 +123,8 @@ private: sal_Unicode buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) }; +static_assert(OUStringLiteral<1>::detail_assertLayout()); + #if defined RTL_STRING_UNITTEST namespace libreoffice_internal { template struct ExceptConstCharArrayDetector> {}; -- cgit