[libcxx-commits] [libcxx] [libc++] Fix initialization-order-fiasco with iostream.cpp constructors (PR #126995)

Vitaly Buka via libcxx-commits libcxx-commits at lists.llvm.org
Fri Feb 14 18:37:29 PST 2025


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/126995

>From baed235d9dac075571ef4f4703b7eabd5326d943 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 12 Feb 2025 17:44:36 -0800
Subject: [PATCH 1/6] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 .../ios_Init/ios_Init.global.pass.cpp         | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp

diff --git a/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp b/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp
new file mode 100644
index 0000000000000..b1ea8517850f4
--- /dev/null
+++ b/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <iostream>
+
+extern "C" const char *__asan_default_options() {
+  return "check_initialization_order=true:strict_init_order=true";
+}
+
+// Test that ios used from globals constructors doesn't trigger
+// Asan initialization-order-fiasco.
+
+struct Global {
+  Global() {
+    std::cout << "Hello!";
+  }
+} global;
+
+int main(int, char**)
+{
+    return 0;
+}

>From c8f96265ba4979dd7588ce717f46b9c5a4c30296 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 12 Feb 2025 21:34:08 -0800
Subject: [PATCH 2/6] with fix

Created using spr 1.3.4
---
 libcxx/src/iostream.cpp                          |  4 ++--
 .../ios.types/ios_Init/ios_Init.global.pass.cpp  | 16 ++++------------
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index d91f9f0c04826..082a46f532db6 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -18,8 +18,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class StreamT, class BufferT>
 union stream_data {
-  stream_data() {}
-  ~stream_data() {}
+  constexpr stream_data() {}
+  constexpr ~stream_data() {}
   struct {
     // The stream has to be the first element, since that's referenced by the stream declarations in <iostream>
     StreamT stream;
diff --git a/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp b/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp
index b1ea8517850f4..ab4fb02ad60fa 100644
--- a/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp
+++ b/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp
@@ -8,20 +8,12 @@
 
 #include <iostream>
 
-extern "C" const char *__asan_default_options() {
-  return "check_initialization_order=true:strict_init_order=true";
-}
+extern "C" const char* __asan_default_options() { return "check_initialization_order=true:strict_init_order=true"; }
 
-// Test that ios used from globals constructors doesn't trigger
-// Asan initialization-order-fiasco.
+// Test that ios used from globals constructors doesn't trigger Asan initialization-order-fiasco.
 
 struct Global {
-  Global() {
-    std::cout << "Hello!";
-  }
+  Global() { std::cout << "Hello!"; }
 } global;
 
-int main(int, char**)
-{
-    return 0;
-}
+int main(int, char**) { return 0; }

>From f9fba09c457020d05d15f7b31eb55cb13c60ec65 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 13 Feb 2025 12:18:52 -0800
Subject: [PATCH 3/6] constinit

Created using spr 1.3.4
---
 libcxx/src/iostream.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index 082a46f532db6..a4c24a36430a4 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -40,11 +40,11 @@ union stream_data {
 
 #ifdef _LIBCPP_ABI_MICROSOFT
 #  define STREAM(StreamT, BufferT, CharT, var)                                                                         \
-    stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__(                                                           \
+    constinit stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__(                                                           \
         "?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT                                                           \
         "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12 at A")
 #else
-#  define STREAM(StreamT, BufferT, CharT, var) stream_data<StreamT<CharT>, BufferT<CharT>> var
+#  define STREAM(StreamT, BufferT, CharT, var) constinit stream_data<StreamT<CharT>, BufferT<CharT>> var
 #endif
 
 // These definitions and the declarations in <iostream> technically cause ODR violations, since they have different

>From 295c2920099961d4dae56555269877ec77c2e9b1 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 13 Feb 2025 12:21:01 -0800
Subject: [PATCH 4/6] format

Created using spr 1.3.4
---
 libcxx/src/iostream.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index a4c24a36430a4..c1713dcb2c5f8 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -40,7 +40,7 @@ union stream_data {
 
 #ifdef _LIBCPP_ABI_MICROSOFT
 #  define STREAM(StreamT, BufferT, CharT, var)                                                                         \
-    constinit stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__(                                                           \
+    constinit stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__(                                                 \
         "?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT                                                           \
         "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12 at A")
 #else

>From 08cb2934f856f7caf2e4e49cf4dc300bca185b43 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Fri, 14 Feb 2025 17:58:10 -0800
Subject: [PATCH 5/6] ={}

Created using spr 1.3.4
---
 libcxx/src/iostream.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index c1713dcb2c5f8..7fa9a2d6d2414 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -42,9 +42,9 @@ union stream_data {
 #  define STREAM(StreamT, BufferT, CharT, var)                                                                         \
     constinit stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__(                                                 \
         "?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT                                                           \
-        "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12 at A")
+        "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12 at A") var = {}
 #else
-#  define STREAM(StreamT, BufferT, CharT, var) constinit stream_data<StreamT<CharT>, BufferT<CharT>> var
+#  define STREAM(StreamT, BufferT, CharT, var) constinit stream_data<StreamT<CharT>, BufferT<CharT>> var = {}
 #endif
 
 // These definitions and the declarations in <iostream> technically cause ODR violations, since they have different

>From 6a98752e813e4efbef7672a54f4330bdeee349dd Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Fri, 14 Feb 2025 18:37:10 -0800
Subject: [PATCH 6/6] CLANG_ONLY

Created using spr 1.3.4
---
 libcxx/src/iostream.cpp | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index 7fa9a2d6d2414..36fe25203a330 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -38,13 +38,20 @@ union stream_data {
 #define CHAR_MANGLING_wchar_t "_W"
 #define CHAR_MANGLING(CharT) CHAR_MANGLING_##CharT
 
+#ifdef _LIBCPP_COMPILER_CLANG_BASED
+#  define STRING_DATA_CONSTINIT constinit
+#else
+#  define STRING_DATA_CONSTINIT
+#endif
+
 #ifdef _LIBCPP_ABI_MICROSOFT
 #  define STREAM(StreamT, BufferT, CharT, var)                                                                         \
-    constinit stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__(                                                 \
+    STRING_DATA_CONSTINIT stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__(                                     \
         "?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT                                                           \
         "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12 at A") var = {}
 #else
-#  define STREAM(StreamT, BufferT, CharT, var) constinit stream_data<StreamT<CharT>, BufferT<CharT>> var = {}
+#  define STREAM(StreamT, BufferT, CharT, var)                                                                         \
+    STRING_DATA_CONSTINIT stream_data<StreamT<CharT>, BufferT<CharT>> var = {}
 #endif
 
 // These definitions and the declarations in <iostream> technically cause ODR violations, since they have different



More information about the libcxx-commits mailing list