From 41db97537ae4f6df251489640f517ceb1e2b7286 Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Thu, 4 Aug 2016 15:05:50 -0700 Subject: [PATCH] Assume p is not nullptr in storeUnaligned Summary: Because we're constructing the value with a placement new, which has some of C++'s most unhelpful behavior ever put into the spec: If `p` is `nullptr` and we are not compiling in C++14 mode, where the restriction was changed, then the placement new will do absolutely nothing at all. By adding the assumption that `p` is not `nullptr`, we'll trip a segfault in release mode rather than failing silently. Note that MSVC would generate the nullptr check regardless of which mode it's in, so this assume forces the removal of the check. Reviewed By: yfeldblum Differential Revision: D3651116 fbshipit-source-id: ee15a38f85ce4e3cb3186fda0b7bcca39acda27a --- folly/Bits.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/folly/Bits.h b/folly/Bits.h index 0a649b82..43ceb40a 100644 --- a/folly/Bits.h +++ b/folly/Bits.h @@ -65,6 +65,7 @@ #include #include +#include #include #include #include @@ -546,6 +547,12 @@ inline void storeUnaligned(void* p, T value) { static_assert(sizeof(Unaligned) == sizeof(T), "Invalid unaligned size"); static_assert(alignof(Unaligned) == 1, "Invalid alignment"); if (kHasUnalignedAccess) { + // Prior to C++14, the spec says that a placement new like this + // is required to check that p is not nullptr, and to do nothing + // if p is a nullptr. By assuming it's not a nullptr, we get a + // nice loud segfault in optimized builds if p is nullptr, rather + // than just silently doing nothing. + folly::assume(p != nullptr); new (p) Unaligned(value); } else { memcpy(p, &value, sizeof(T)); -- 2.34.1