diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp index d91f9f0c04826..416725235c340 100644 --- a/libcxx/src/iostream.cpp +++ b/libcxx/src/iostream.cpp @@ -18,8 +18,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template 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 StreamT stream; @@ -38,13 +38,19 @@ 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) \ - stream_data, BufferT> var __asm__( \ + STRING_DATA_CONSTINIT stream_data, BufferT> var __asm__( \ "?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT \ "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12@A") #else -# define STREAM(StreamT, BufferT, CharT, var) stream_data, BufferT> var +# define STREAM(StreamT, BufferT, CharT, var) STRING_DATA_CONSTINIT stream_data, BufferT> var #endif // These definitions and the declarations in technically cause ODR violations, since they have different 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..ac6a7213bb722 --- /dev/null +++ b/libcxx/test/std/input.output/iostreams.base/ios.base/ios.types/ios_Init/ios_Init.global.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// FIXME: Remove after issue https://github.com/llvm/llvm-project/issues/127348 resolved. +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; }