Bug 1145056 - Assert that the guard notifier has been initialized. r=froydnj
authorEric Rahm <erahm@mozilla.com>
Tue, 21 Apr 2015 16:47:52 -0700
changeset 273310 43e99677905e6431b55d6fd1da11c19439e26efd
parent 273309 004350b7a05d12b7c0bfe72b9165a40757d80c4b
child 273311 3ce2f7f110af4f7139fe9edc4d11efb391a07e81
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1145056
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1145056 - Assert that the guard notifier has been initialized. r=froydnj In order to both verify that guard object notifiers are being properly used and to silence a coverity warning about an explicit null dereference we switch over to using a poison value rather than nullptr. An assertion is added to make sure that the guard object notifier is properly initialized as well.
mfbt/GuardObjects.h
--- a/mfbt/GuardObjects.h
+++ b/mfbt/GuardObjects.h
@@ -5,23 +5,30 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Implementation of macros to ensure correct use of RAII Auto* objects. */
 
 #ifndef mozilla_GuardObjects_h
 #define mozilla_GuardObjects_h
 
 #include "mozilla/Assertions.h"
+#include "mozilla/Move.h"
 #include "mozilla/Types.h"
-#include "mozilla/Move.h"
 
 #ifdef __cplusplus
 
 #ifdef DEBUG
 
+/**
+ * A custom define is used rather than |mozPoisonValue()| due to cascading
+ * build failures relating to how mfbt is linked on different operating
+ * systems. See bug 1160253.
+ */
+#define MOZ_POISON uintptr_t(-1)
+
 namespace mozilla {
 namespace detail {
 
 /*
  * The following classes are designed to cause assertions to detect
  * inadvertent use of guard objects as temporaries. In other words,
  * when we have a guard object whose only purpose is its constructor and
  * destructor (and is never otherwise referenced), the intended use
@@ -69,19 +76,30 @@ namespace detail {
  * https://developer.mozilla.org/en/Using_RAII_classes_in_Mozilla
  */
 class GuardObjectNotifier
 {
 private:
   bool* mStatementDone;
 
 public:
-  GuardObjectNotifier() : mStatementDone(nullptr) { }
+  GuardObjectNotifier()
+    : mStatementDone(reinterpret_cast<bool*>(MOZ_POISON))
+  {
+  }
 
-  ~GuardObjectNotifier() { *mStatementDone = true; }
+  ~GuardObjectNotifier()
+  {
+    // Assert that the GuardObjectNotifier has been properly initialized by
+    // using the |MOZ_GUARD_OBJECT_NOTIFIER_INIT| macro. A poison value is
+    // used rather than a null check to appease static analyzers that were
+    // (incorrectly) detecting null pointer dereferences.
+    MOZ_ASSERT(mStatementDone != reinterpret_cast<bool*>(MOZ_POISON));
+    *mStatementDone = true;
+  }
 
   void setStatementDone(bool* aStatementIsDone)
   {
     mStatementDone = aStatementIsDone;
   }
 };
 
 class GuardObjectNotificationReceiver
@@ -105,16 +123,18 @@ public:
   {
     aNotifier.setStatementDone(&mStatementDone);
   }
 };
 
 } /* namespace detail */
 } /* namespace mozilla */
 
+#undef MOZ_POISON
+
 #endif /* DEBUG */
 
 #ifdef DEBUG
 #  define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER \
      mozilla::detail::GuardObjectNotificationReceiver _mCheckNotUsedAsTemporary;
 #  define MOZ_GUARD_OBJECT_NOTIFIER_PARAM \
      , mozilla::detail::GuardObjectNotifier&& _notifier = \
          mozilla::detail::GuardObjectNotifier()