Bug 1448494 - store/expose uintptr_t -- WIP I will roll this into the other patches if accepted - r?froydnj draft
authorGerald Squelart <gsquelart@mozilla.com>
Tue, 10 Apr 2018 12:03:26 +1000
changeset 790887 0775e7cebf810f7961c6d8c9840acee09c7ab699
parent 790886 7e69939cb3688b686e9eb4396d8d30fef52f926d
push id108622
push usergsquelart@mozilla.com
push dateWed, 02 May 2018 23:44:21 +0000
reviewersfroydnj
bugs1448494
milestone61.0a1
Bug 1448494 - store/expose uintptr_t -- WIP I will roll this into the other patches if accepted - r?froydnj MozReview-Commit-ID: Brv0ENajgYw
dom/media/doctor/DecoderDoctorLogger.h
mfbt/NonDereferenceable.h
mfbt/tests/TestNonDereferenceable.cpp
--- a/dom/media/doctor/DecoderDoctorLogger.h
+++ b/dom/media/doctor/DecoderDoctorLogger.h
@@ -286,29 +286,30 @@ public:
   }
 
   template<typename Subject>
   static void LogConstruction(NonDereferenceable<const Subject> aSubject)
   {
     using Traits = DDLoggedTypeTraits<Subject>;
     if (!Traits::HasBase::value) {
       Log(DDLoggedTypeTraits<Subject>::Name(),
-          aSubject.value(),
+          reinterpret_cast<const void*>(aSubject.value()),
           DDLogCategory::_Construction,
           "",
           DDLogValue{ DDNoValue{} });
     } else {
       Log(DDLoggedTypeTraits<Subject>::Name(),
-          aSubject.value(),
+          reinterpret_cast<const void*>(aSubject.value()),
           DDLogCategory::_DerivedConstruction,
           "",
           DDLogValue{ DDLogObject{
             DDLoggedTypeTraits<typename Traits::BaseType>::Name(),
-            NonDereferenceable<const typename Traits::BaseType>(aSubject)
-              .value() } });
+            reinterpret_cast<const void*>(
+              NonDereferenceable<const typename Traits::BaseType>(aSubject)
+                .value()) } });
     }
   }
 
   template<typename Subject>
   static void LogConstruction(const Subject* aSubject)
   {
     LogConstruction(NonDereferenceable<const Subject>(aSubject));
   }
@@ -322,17 +323,17 @@ public:
         "",
         DDLogValue{ DDNoValue{} });
   }
 
   template<typename Subject>
   static void LogDestruction(NonDereferenceable<const Subject> aSubject)
   {
     Log(DDLoggedTypeTraits<Subject>::Name(),
-        aSubject.value(),
+        reinterpret_cast<const void*>(aSubject.value()),
         DDLogCategory::_Destruction,
         "",
         DDLogValue{ DDNoValue{} });
   }
 
   template<typename Subject>
   static void LogDestruction(const Subject* aSubject)
   {
--- a/mfbt/NonDereferenceable.h
+++ b/mfbt/NonDereferenceable.h
@@ -7,16 +7,18 @@
 #ifndef mozilla_NonDereferenceable_h
 #define mozilla_NonDereferenceable_h
 
 /* A pointer wrapper indicating that the pointer should not be dereferenced. */
 
 #include "mozilla/Attributes.h"
 #include "mozilla/TypeTraits.h"
 
+#include <cstdint>
+
 // Macro indicating that a function manipulates a pointer that will not be
 // dereferenced, and therefore there is no need to check the object.
 #if defined(__clang__)
 #define NO_POINTEE_CHECKS __attribute__((no_sanitize("vptr")))
 #else
 #define NO_POINTEE_CHECKS /* nothing */
 #endif
 
@@ -113,22 +115,19 @@ public:
   // at these lines:
   T& operator*() = delete;  // Cannot dereference NonDereferenceable!
   T* operator->() = delete; // Cannot dereference NonDereferenceable!
 
   // Null check.
   NO_POINTEE_CHECKS
   explicit operator bool() const { return !!mPtr; }
 
-  // Extract the pointer value, untyped, but with the same constness as T.
-  // Safe to use as a pure pointer value for e.g. logging purposes.
-  // Please do not cast this value back to T*.
-  using Void = typename Conditional<IsConst<T>::value, const void, void>::Type;
+  // Extract the pointer value, untyped.
   NO_POINTEE_CHECKS
-  Void* value() const { return static_cast<Void*>(mPtr); }
+  uintptr_t value() const { return reinterpret_cast<uintptr_t>(mPtr); }
 
 private:
   // Let other NonDereferenceable templates access mPtr, to permit construction/
   // assignment from compatible pointer types.
   template<typename> friend class NonDereferenceable;
 
   T* MOZ_NON_OWNING_REF mPtr;
 };
--- a/mfbt/tests/TestNonDereferenceable.cpp
+++ b/mfbt/tests/TestNonDereferenceable.cpp
@@ -23,41 +23,41 @@ TestNonDereferenceableSimple()
   CHECK(!nd0.value());
 
   int i = 1;
   int i2 = 2;
 
   // Construction with pointer.
   NonDereferenceable<int> nd1(&i);
   CHECK(!!nd1);
-  CHECK(nd1.value() == static_cast<void*>(&i));
+  CHECK(nd1.value() == reinterpret_cast<uintptr_t>(&i));
 
   // Assignment with pointer.
   nd1 = &i2;
-  CHECK(nd1.value() == static_cast<void*>(&i2));
+  CHECK(nd1.value() == reinterpret_cast<uintptr_t>(&i2));
 
   // Copy-construction.
   NonDereferenceable<int> nd2(nd1);
-  CHECK(nd2.value() == static_cast<void*>(&i2));
+  CHECK(nd2.value() == reinterpret_cast<uintptr_t>(&i2));
 
   // Copy-assignment.
   nd2 = nd0;
   CHECK(!nd2.value());
 
   // Move-construction.
   NonDereferenceable<int> nd3{ NonDereferenceable<int>(&i) };
-  CHECK(nd3.value() == static_cast<void*>(&i));
+  CHECK(nd3.value() == reinterpret_cast<uintptr_t>(&i));
 
   // Move-assignment.
   nd3 = Move(nd1);
-  CHECK(nd3.value() == static_cast<void*>(&i2));
+  CHECK(nd3.value() == reinterpret_cast<uintptr_t>(&i2));
   // Note: Not testing nd1's value because we don't want to assume what state
   // it is left in after move. But at least it should be reusable:
   nd1 = &i;
-  CHECK(nd1.value() == static_cast<void*>(&i));
+  CHECK(nd1.value() == reinterpret_cast<uintptr_t>(&i));
 }
 
 void
 TestNonDereferenceableHierarchy()
 {
   struct Base1
   {
     // Member variable, to make sure Base1 is not empty.
@@ -73,43 +73,43 @@ TestNonDereferenceableHierarchy()
   {
   };
 
   Derived d;
 
   // Construct NonDereferenceable from raw pointer.
   NonDereferenceable<Derived> ndd = NonDereferenceable<Derived>(&d);
   CHECK(ndd);
-  CHECK(ndd.value() == static_cast<void*>(&d));
+  CHECK(ndd.value() == reinterpret_cast<uintptr_t>(&d));
 
   // Cast Derived to Base1.
   NonDereferenceable<Base1> ndb1 = ndd;
   CHECK(ndb1);
-  CHECK(ndb1.value() == static_cast<void*>(static_cast<Base1*>(&d)));
+  CHECK(ndb1.value() == reinterpret_cast<uintptr_t>(static_cast<Base1*>(&d)));
 
   // Cast Base1 back to Derived.
   NonDereferenceable<Derived> nddb1 = ndb1;
-  CHECK(nddb1.value() == static_cast<void*>(&d));
+  CHECK(nddb1.value() == reinterpret_cast<uintptr_t>(&d));
 
   // Cast Derived to Base2.
   NonDereferenceable<Base2> ndb2 = ndd;
   CHECK(ndb2);
-  CHECK(ndb2.value() == static_cast<void*>(static_cast<Base2*>(&d)));
+  CHECK(ndb2.value() == reinterpret_cast<uintptr_t>(static_cast<Base2*>(&d)));
   // Sanity check that Base2 should be offset from the start of Derived.
   CHECK(ndb2.value() != ndd.value());
 
   // Cast Base2 back to Derived.
   NonDereferenceable<Derived> nddb2 = ndb2;
-  CHECK(nddb2.value() == static_cast<void*>(&d));
+  CHECK(nddb2.value() == reinterpret_cast<uintptr_t>(&d));
 
   // Note that it's not possible to jump between bases, as they're not obviously
   // related, i.e.: `NonDereferenceable<Base2> ndb22 = ndb1;` doesn't compile.
   // However it's possible to explicitly navigate through the derived object:
   NonDereferenceable<Base2> ndb22 = NonDereferenceable<Derived>(ndb1);
-  CHECK(ndb22.value() == static_cast<void*>(static_cast<Base2*>(&d)));
+  CHECK(ndb22.value() == reinterpret_cast<uintptr_t>(static_cast<Base2*>(&d)));
 
   // Handling nullptr; should stay nullptr even for offset bases.
   ndd = nullptr;
   CHECK(!ndd);
   CHECK(!ndd.value());
   ndb1 = ndd;
   CHECK(!ndb1);
   CHECK(!ndb1.value());
@@ -143,49 +143,49 @@ TestNonDereferenceableCRTP()
   {
   };
   using Base1 = Derived::CRTPBase<Derived, 1>;
   using Base2 = Derived::CRTPBase<Derived, 2>;
 
   Derived d;
   // Verify that base constructors have correctly captured the address of the
   // (at the time still incomplete) derived object.
-  CHECK(d.Base1::mDerived.value() == static_cast<void*>(&d));
-  CHECK(d.Base2::mDerived.value() == static_cast<void*>(&d));
+  CHECK(d.Base1::mDerived.value() == reinterpret_cast<uintptr_t>(&d));
+  CHECK(d.Base2::mDerived.value() == reinterpret_cast<uintptr_t>(&d));
 
   // Construct NonDereferenceable from raw pointer.
   NonDereferenceable<Derived> ndd = NonDereferenceable<Derived>(&d);
   CHECK(ndd);
-  CHECK(ndd.value() == static_cast<void*>(&d));
+  CHECK(ndd.value() == reinterpret_cast<uintptr_t>(&d));
 
   // Cast Derived to Base1.
   NonDereferenceable<Base1> ndb1 = ndd;
   CHECK(ndb1);
-  CHECK(ndb1.value() == static_cast<void*>(static_cast<Base1*>(&d)));
+  CHECK(ndb1.value() == reinterpret_cast<uintptr_t>(static_cast<Base1*>(&d)));
 
   // Cast Base1 back to Derived.
   NonDereferenceable<Derived> nddb1 = ndb1;
-  CHECK(nddb1.value() == static_cast<void*>(&d));
+  CHECK(nddb1.value() == reinterpret_cast<uintptr_t>(&d));
 
   // Cast Derived to Base2.
   NonDereferenceable<Base2> ndb2 = ndd;
   CHECK(ndb2);
-  CHECK(ndb2.value() == static_cast<void*>(static_cast<Base2*>(&d)));
+  CHECK(ndb2.value() == reinterpret_cast<uintptr_t>(static_cast<Base2*>(&d)));
   // Sanity check that Base2 should be offset from the start of Derived.
   CHECK(ndb2.value() != ndd.value());
 
   // Cast Base2 back to Derived.
   NonDereferenceable<Derived> nddb2 = ndb2;
-  CHECK(nddb2.value() == static_cast<void*>(&d));
+  CHECK(nddb2.value() == reinterpret_cast<uintptr_t>(&d));
 
   // Note that it's not possible to jump between bases, as they're not obviously
   // related, i.e.: `NonDereferenceable<Base2> ndb22 = ndb1;` doesn't compile.
   // However it's possible to explicitly navigate through the derived object:
   NonDereferenceable<Base2> ndb22 = NonDereferenceable<Derived>(ndb1);
-  CHECK(ndb22.value() == static_cast<void*>(static_cast<Base2*>(&d)));
+  CHECK(ndb22.value() == reinterpret_cast<uintptr_t>(static_cast<Base2*>(&d)));
 }
 
 int
 main()
 {
   TestNonDereferenceableSimple();
   TestNonDereferenceableHierarchy();
   TestNonDereferenceableCRTP();