From 9fec814a9a1459b88fec7b569db99ccb12d5362b Mon Sep 17 00:00:00 2001 From: Omer Ozarslan Date: Mon, 29 Dec 2025 10:17:12 -0800 Subject: [PATCH] Launder dereferencing type-punned address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a small patch to avoid strict aliasing issues manifested in GCC I came across a while ago. The test case was complex and the failing assertion with a matcher was present only with `-O3`, so I don't have a standalone test. However, I manually confirmed adding `-fno-strict-aliasing` fixed the issue before this patch, and `-O3` behaved as intended after this patch without turning strict-aliasing off. There is a similar previous change in https://github.com/google/googletest/commit/50ce52016139a4346a94df71249c14c5d286e000. For the relevant clause from the C++17 standard, refer to below note from https://timsong-cpp.github.io/cppwp/n4659/basic.life#8: > [ Note: If these conditions are not met, a pointer to the new object can be obtained from a pointer that represents the address of its storage by calling std::launder ([support.dynamic]).  — end note ] --- googletest/include/gtest/gtest-matchers.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index 08ffbeb9..8631286b 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -402,11 +403,9 @@ class [[nodiscard]] MatcherBase : private MatcherDescriberInterface { template ()> struct ValuePolicy { static const M& Get(const MatcherBase& m) { - // When inlined along with Init, need to be explicit to avoid violating + // When inlined along with Init, need to be laundered to avoid violating // strict aliasing rules. - const M* ptr = - static_cast(static_cast(&m.buffer_)); - return *ptr; + return *std::launder(reinterpret_cast(&m.buffer_)); } static void Init(MatcherBase& m, M impl) { ::new (static_cast(&m.buffer_)) M(impl);