folly/experimental/Bits.h + ASan
authorPhilip Pronin <philipp@fb.com>
Fri, 7 Mar 2014 08:49:24 +0000 (00:49 -0800)
committerDave Watson <davejwatson@fb.com>
Mon, 10 Mar 2014 20:51:09 +0000 (13:51 -0700)
Summary: Allow disabling ASan for `folly::Bits`.

Test Plan: [fb-only]

Reviewed By: soren@fb.com

FB internal diff: D1208584

folly/experimental/Bits.h

index 7750f3fccefa8fe3e6e0b7c61e95d05ef9377aa7..62f73702524ca65c23d9281d751432f8aca203a7 100644 (file)
@@ -27,6 +27,9 @@
 
 namespace folly {
 
+template <class T>
+struct UnalignedNoASan : public Unaligned<T> { };
+
 // As a general rule, bit operations work on unsigned values only;
 // right-shift is arithmetic for signed values, and that can lead to
 // unpleasant bugs.
@@ -62,6 +65,28 @@ struct BitsTraits<Unaligned<T>, typename std::enable_if<
   }
 };
 
+// Special version that allows to disable address sanitizer on demand.
+template <class T>
+struct BitsTraits<UnalignedNoASan<T>, typename std::enable_if<
+    (std::is_integral<T>::value && std::is_unsigned<T>::value)>::type> {
+  typedef T UnderlyingType;
+  static T FOLLY_DISABLE_ADDRESS_SANITIZER
+  load(const UnalignedNoASan<T>& x) { return x.value; }
+  static void FOLLY_DISABLE_ADDRESS_SANITIZER
+  store(UnalignedNoASan<T>& x, T v) { x.value = v; }
+  static T FOLLY_DISABLE_ADDRESS_SANITIZER
+  loadRMW(const UnalignedNoASan<T>& x) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+// make sure we compile without warning on gcc 4.6 with -Wpragmas
+#if __GNUC_PREREQ(4, 7)
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+    return x.value;
+#pragma GCC diagnostic pop
+  }
+};
+
 // Partial specialization for T, where T is unsigned integral
 template <class T>
 struct BitsTraits<T, typename std::enable_if<
@@ -79,6 +104,7 @@ struct BitsTraits<T, typename std::enable_if<
 #pragma GCC diagnostic pop
   }
 };
+
 }  // namespace detail
 
 /**