Make DEFINE_GLOBAL C++17 compliant. The pointer to an object is not interconvertible with the pointer to its underlying storage, and GCC raises a Wstrict-aliasing warning about UB resulting from the dereference. (This is really a pointer provenance issue, not a type aliasing issue, as the underlying void*[] is never actually directly used) Additionally, void* potentially has a too-small alignment for some types (eg. long double). We fix the fist issue by memory laundering, and the second by switching to aligned_storage_t. --- src/third_party/blink/renderer/platform/wtf/static_constructors.h.old 2022-10-20 19:00:30.237477900 +0200 +++ src/third_party/blink/renderer/platform/wtf/static_constructors.h 2022-10-29 21:48:44.336995700 +0200 @@ -21,8 +21,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_STATIC_CONSTRUCTORS_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_STATIC_CONSTRUCTORS_H_ +#include +#include + // We need to avoid having static constructors. This is accomplished by defining -// a static array of the appropriate size and alignment, and defining a const +// a buffer of the appropriate size and alignment, and defining a const // reference that points to the buffer. During initialization, the object will // be constructed with placement new into the buffer. This works with MSVC, GCC, // and Clang without producing dynamic initialization code even at -O0. The only @@ -33,7 +36,7 @@ // Use an array of pointers instead of an array of char in case there is some // alignment issue. #define DEFINE_GLOBAL(type, name) \ - void* name##Storage[(sizeof(type) + sizeof(void*) - 1) / sizeof(void*)]; \ - const type& name = *reinterpret_cast(&name##Storage) + std::aligned_storage_t name##Storage; \ + const type& name = *std::launder(reinterpret_cast(&name##Storage)) #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_STATIC_CONSTRUCTORS_H_