summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-09-21 21:01:40 +0200
committerStephan Bergmann <sbergman@redhat.com>2020-09-21 22:29:31 +0200
commit52a49f9e480ca03e231cfda82640a928393131c9 (patch)
treef685aaeec9787e9f5aa2940514c4533b1a59bc86 /include
parente79a6a5270d190d6e89a6acf08e22419386d2117 (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.hxx21
-rw-r--r--include/rtl/ustring.hxx20
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>> {};