diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2020-09-21 21:01:40 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2020-09-21 22:29:31 +0200 |
commit | 52a49f9e480ca03e231cfda82640a928393131c9 (patch) | |
tree | f685aaeec9787e9f5aa2940514c4533b1a59bc86 /include | |
parent | e79a6a5270d190d6e89a6acf08e22419386d2117 (diff) |
static_assert that O[U]StringLiteral are layout compatible with rtl_[u]String
...as was suggested by Mike Kaganski in a comment at
<https://gerrit.libreoffice.org/c/core/+/102222/10#
message-aa8bcf42f04686766440e2848c7d1f76f474f2f8> "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 <sbergman@redhat.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/rtl/string.hxx | 21 | ||||
-rw-r--r-- | include/rtl/ustring.hxx | 20 |
2 files changed, 41 insertions, 0 deletions
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 <cassert> #include <cstddef> +#include <cstdlib> #include <limits> #include <new> #include <ostream> @@ -32,6 +33,7 @@ #if defined LIBO_INTERNAL_ONLY #include <string_view> +#include <type_traits> #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<decltype(refCount), decltype(rtl_String::refCount)>); + static_assert(offsetof(OStringLiteral, length) == offsetof(rtl_String, length)); + static_assert(std::is_same_v<decltype(length), decltype(rtl_String::length)>); + static_assert(offsetof(OStringLiteral, buffer) == offsetof(rtl_String, buffer)); + static_assert( + std::is_same_v< + std::remove_extent_t<decltype(buffer)>, + std::remove_extent_t<decltype(rtl_String::buffer)>>); + 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 <cassert> #include <cstddef> +#include <cstdlib> #include <limits> #include <new> #include <ostream> @@ -31,6 +32,7 @@ #if defined LIBO_INTERNAL_ONLY #include <string_view> +#include <type_traits> #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<decltype(refCount), decltype(rtl_uString::refCount)>); + static_assert(offsetof(OUStringLiteral, length) == offsetof(rtl_uString, length)); + static_assert(std::is_same_v<decltype(length), decltype(rtl_uString::length)>); + static_assert(offsetof(OUStringLiteral, buffer) == offsetof(rtl_uString, buffer)); + static_assert( + std::is_same_v< + std::remove_extent_t<decltype(buffer)>, + std::remove_extent_t<decltype(rtl_uString::buffer)>>); + 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<std::size_t N> struct ExceptConstCharArrayDetector<OUStringLiteral<N>> {}; |