Silence -Wuninitialized in some cases
authorTudor Bosman <tudorb@fb.com>
Thu, 13 Dec 2012 18:31:51 +0000 (10:31 -0800)
committerJordan DeLong <jdelong@fb.com>
Sun, 16 Dec 2012 22:49:31 +0000 (14:49 -0800)
Test Plan: compiles

Reviewed By: philipp@fb.com

FB internal diff: D657623

folly/Bits.h
folly/experimental/Bits.h

index 38d35723175f5e5e73fcdcbd3f1e525fc924589d..a88e6349254dd30269447b34ec587d7136124007 100644 (file)
@@ -498,7 +498,7 @@ template <class T>
 struct Unaligned<
     T,
     typename std::enable_if<std::is_pod<T>::value>::type> {
-  Unaligned() { }  // uninitialized
+  Unaligned() = default;  // uninitialized
   /* implicit */ Unaligned(T v) : value(v) { }
   T value;
 } __attribute__((packed));
index e3ec6eb6a889e02556a9319637f651aea5f698b8..214bd66a27bd4cd088abd6607aac1c2a8088beb4 100644 (file)
@@ -40,12 +40,21 @@ namespace detail {
 template <class T, class Enable=void> struct BitsTraits;
 
 // Partial specialization for Unaligned<T>, where T is unsigned integral
+// loadRMW is the same as load, but it indicates that it loads for a
+// read-modify-write operation (we write back the bits we won't change);
+// silence the GCC warning in that case.
 template <class T>
 struct BitsTraits<Unaligned<T>, typename std::enable_if<
     (std::is_integral<T>::value && std::is_unsigned<T>::value)>::type> {
   typedef T UnderlyingType;
   static T load(const Unaligned<T>& x) { return x.value; }
   static void store(Unaligned<T>& x, T v) { x.value = v; }
+  static T loadRMW(const Unaligned<T>& x) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+    return x.value;
+#pragma GCC diagnostic pop
+  }
 };
 
 // Partial specialization for T, where T is unsigned integral
@@ -55,6 +64,12 @@ struct BitsTraits<T, typename std::enable_if<
   typedef T UnderlyingType;
   static T load(const T& x) { return x; }
   static void store(T& x, T v) { x = v; }
+  static T loadRMW(const T& x) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+    return x;
+#pragma GCC diagnostic pop
+  }
 };
 }  // namespace detail
 
@@ -147,13 +162,13 @@ struct Bits {
 template <class T, class Traits>
 inline void Bits<T, Traits>::set(T* p, size_t bit) {
   T& block = p[blockIndex(bit)];
-  Traits::store(block, Traits::load(block) | (one << bitOffset(bit)));
+  Traits::store(block, Traits::loadRMW(block) | (one << bitOffset(bit)));
 }
 
 template <class T, class Traits>
 inline void Bits<T, Traits>::clear(T* p, size_t bit) {
   T& block = p[blockIndex(bit)];
-  Traits::store(block, Traits::load(block) & ~(one << bitOffset(bit)));
+  Traits::store(block, Traits::loadRMW(block) & ~(one << bitOffset(bit)));
 }
 
 template <class T, class Traits>
@@ -201,7 +216,7 @@ template <class T, class Traits>
 inline void Bits<T, Traits>::innerSet(T* p, size_t offset, size_t count,
                                       UnderlyingType value) {
   // Mask out bits and set new value
-  UnderlyingType v = Traits::load(*p);
+  UnderlyingType v = Traits::loadRMW(*p);
   v &= ~(((one << count) - 1) << offset);
   v |= (value << offset);
   Traits::store(*p, v);