mirror of
https://github.com/google/googletest.git
synced 2026-02-07 10:19:53 +08:00
Launder dereferencing type-punned address
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 50ce520161.
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 ]
This commit is contained in:
parent
9156d4caac
commit
9fec814a9a
@ -42,6 +42,7 @@
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@ -402,11 +403,9 @@ class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
|
||||
template <typename M, bool = MatcherBase::IsInlined<M>()>
|
||||
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<const M*>(static_cast<const void*>(&m.buffer_));
|
||||
return *ptr;
|
||||
return *std::launder(reinterpret_cast<const M*>(&m.buffer_));
|
||||
}
|
||||
static void Init(MatcherBase& m, M impl) {
|
||||
::new (static_cast<void*>(&m.buffer_)) M(impl);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user