include/rtl/string.hxx                              |   19 +++++++++----------
 include/rtl/ustring.hxx                             |   19 +++++++++----------
 sal/qa/rtl/strings/test_ostring_stringliterals.cxx  |   19 +++++++++++++++++++
 sal/qa/rtl/strings/test_oustring_stringliterals.cxx |   16 ++++++++++++++++
 4 files changed, 53 insertions(+), 20 deletions(-)

New commits:
commit bd94e9dfd0a4c67266e21baa9ec10a56850d093f
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Tue Mar 29 16:28:05 2022 +0200
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Tue Mar 29 21:15:13 2022 +0200

    Add back the opportunity to leave O[U]StringLiteral's buffer uninitialized
    
    ...once we have a C++20 baseline, which would render uses of the consteval
    O[U]StringLiteral ctors ill-formed if we accidentally failed to write to 
all of
    buffer's elements.  This had been broken (and the TODO comments had become
    misleading) with 21584b304b21bfe6b99b6f29018c6b754ea28fc0 "make
    OUString(OUStringLiteral) constructor constexpr" and
    bca539e889d40e06cb3275442622cb075b2484a2 "make OString(OStringLiteral)
    constructor constexpr".
    
    Also add corresponding test code.
    
    Change-Id: I2bc680282c717d403a681ff4b9396580c8382de1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132275
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sberg...@redhat.com>

diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx
index 440f80900855..e99581cd6f94 100644
--- a/include/rtl/string.hxx
+++ b/include/rtl/string.hxx
@@ -135,18 +135,17 @@ private:
         static_assert(offsetof(OStringLiteral, str.buffer) == 
offsetof(OStringLiteral, more.buffer));
     }
 
+    struct Data {
+        Data() = default;
+
+        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)
+    };
+
     union {
         rtl_String str;
-        struct {
-            oslInterlockedCount refCount;
-            sal_Int32 length;
-            char buffer[N];
-        } more =
-            {
-                0x40000000, // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
-                N - 1,
-                {} //TODO: drop initialization for C++20 (P1331R2)
-            };
+        Data more = {};
     };
 };
 #endif
diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx
index 4d983a089f72..1a6a1cae8990 100644
--- a/include/rtl/ustring.hxx
+++ b/include/rtl/ustring.hxx
@@ -117,18 +117,17 @@ private:
         static_assert(offsetof(OUStringLiteral, str.buffer) == 
offsetof(OUStringLiteral, more.buffer));
     }
 
+    struct Data {
+        Data() = default;
+
+        oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG 
(sal/rtl/strimp.hxx)
+        sal_Int32 length = N - 1;
+        sal_Unicode buffer[N] = {}; //TODO: drop initialization for C++20 
(P1331R2)
+    };
+
     union {
         rtl_uString str;
-        struct {
-            oslInterlockedCount refCount;
-            sal_Int32 length;
-            sal_Unicode buffer[N];
-        } more =
-            {
-                0x40000000, // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
-                N - 1,
-                {} //TODO: drop initialization for C++20 (P1331R2)
-            };
+        Data more = {};
     };
 };
 
diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx 
b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
index e513d56a5d8f..ec0faec94f18 100644
--- a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
@@ -27,6 +27,7 @@ class StringLiterals: public CppUnit::TestFixture
 {
 private:
     void checkCtors();
+    void checkConstexprCtor();
     void checkUsage();
     void checkNonConstUsage();
     void checkBuffer();
@@ -36,8 +37,12 @@ private:
     static const char bad5[];
     static char bad6[];
 
+    // Check that OStringLiteral ctor is actually constexpr:
+    static constexpr rtlunittest::OStringLiteral dummy{"dummy"};
+
 CPPUNIT_TEST_SUITE(StringLiterals);
 CPPUNIT_TEST(checkCtors);
+CPPUNIT_TEST(checkConstexprCtor);
 CPPUNIT_TEST(checkUsage);
 CPPUNIT_TEST(checkNonConstUsage);
 CPPUNIT_TEST(checkBuffer);
@@ -110,6 +115,20 @@ void test::ostring::StringLiterals::testcall( const char 
str[] )
 #endif
 }
 
+void test::ostring::StringLiterals::checkConstexprCtor()
+{
+#if __cplusplus >= 202002L
+    static constinit
+#endif
+    rtl::OString s(dummy);
+    CPPUNIT_ASSERT_EQUAL(oslInterlockedCount(0x40000000), s.pData->refCount);
+        // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), s.getLength());
+    CPPUNIT_ASSERT_EQUAL(rtl::OString("dummy"), s);
+    CPPUNIT_ASSERT_EQUAL(
+        static_cast<void const *>(dummy.getStr()), static_cast<void const 
*>(s.getStr()));
+}
+
 void test::ostring::StringLiterals::checkUsage()
 {
 // simply check that all string literal based calls work as expected
diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx 
b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
index 9227cac84e7e..0caa3fc03579 100644
--- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
@@ -34,6 +34,7 @@ class StringLiterals: public CppUnit::TestFixture
 {
 private:
     void checkCtors();
+    void checkConstexprCtor();
     void checkUsage();
     void checkBuffer();
     void checkOUStringLiteral();
@@ -48,6 +49,7 @@ private:
 
 CPPUNIT_TEST_SUITE(StringLiterals);
 CPPUNIT_TEST(checkCtors);
+CPPUNIT_TEST(checkConstexprCtor);
 CPPUNIT_TEST(checkUsage);
 CPPUNIT_TEST(checkBuffer);
 CPPUNIT_TEST(checkOUStringLiteral);
@@ -118,6 +120,20 @@ void test::oustring::StringLiterals::testcall( const char 
str[] )
         !VALID_CONVERSION_CALL([&str]() { return rtl::OUString(str); }));
 }
 
+void test::oustring::StringLiterals::checkConstexprCtor()
+{
+#if __cplusplus >= 202002L
+    static constinit
+#endif
+    rtl::OUString s(dummy);
+    CPPUNIT_ASSERT_EQUAL(oslInterlockedCount(0x40000000), s.pData->refCount);
+        // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), s.getLength());
+    CPPUNIT_ASSERT_EQUAL(rtl::OUString("dummy"), s);
+    CPPUNIT_ASSERT_EQUAL(
+        static_cast<void const *>(dummy.getStr()), static_cast<void const 
*>(s.getStr()));
+}
+
 void test::oustring::StringLiterals::checkUsage()
 {
 // simply check that all string literal based calls work as expected

Reply via email to