Assume p is not nullptr in storeUnaligned
authorChristopher Dykes <cdykes@fb.com>
Thu, 4 Aug 2016 22:05:50 +0000 (15:05 -0700)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Thu, 4 Aug 2016 22:08:34 +0000 (15:08 -0700)
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

index 0a649b82caee1565c466a162832844734c9c206c..43ceb40a32376f150dd8162c03657264a9bfdc52 100644 (file)
@@ -65,6 +65,7 @@
 #include <folly/Portability.h>
 #include <folly/portability/Builtins.h>
 
+#include <folly/Assume.h>
 #include <folly/detail/BitsDetail.h>
 #include <folly/detail/BitIteratorDetail.h>
 #include <folly/Likely.h>
@@ -546,6 +547,12 @@ inline void storeUnaligned(void* p, T value) {
   static_assert(sizeof(Unaligned<T>) == sizeof(T), "Invalid unaligned size");
   static_assert(alignof(Unaligned<T>) == 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<T>(value);
   } else {
     memcpy(p, &value, sizeof(T));