/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* A pointer wrapper indicating that the pointer should not be dereferenced. */
#include"mozilla/Attributes.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. #ifdefined(__clang__) # define NO_POINTEE_CHECKS __attribute__((no_sanitize("vptr"))) #else # define NO_POINTEE_CHECKS /* nothing */ #endif
namespace mozilla {
// NonDereferenceable<T> wraps a raw pointer value of type T*, but prevents // dereferencing. // // The main use case is for pointers that referencing memory that may not // contain a valid object, either because the object has already been freed, or // is under active construction or destruction (and hence parts of it may be // uninitialized or destructed.) // Such a pointer may still be useful, e.g., for its numeric value for // logging/debugging purposes, which may be accessed with `value()`. // Using NonDereferenceable with such pointers will make this intent clearer, // and prevent misuses. // // Note that NonDereferenceable is only a wrapper and is NOT an owning pointer, // i.e., it will not release/free the object. // // NonDereferenceable allows conversions between compatible pointer types, e.g., // to navigate a class hierarchy and identify parent/sub-objects. Note that the // converted pointers stay safely NonDereferenceable. // // Use of NonDereferenceable is required to avoid errors from sanitization tools // like `clang++ -fsanitize=vptr`, and should prevent false positives while // pointers are manipulated within NonDereferenceable objects. // template <typename T> class NonDereferenceable { public: // Default construction with a null value.
NonDereferenceable() : mPtr(nullptr) {}
// Default copy construction and assignment.
NO_POINTEE_CHECKS
NonDereferenceable(const NonDereferenceable&) = default;
NO_POINTEE_CHECKS
NonDereferenceable<T>& operator=(const NonDereferenceable&) = default; // No move operations, as we're only carrying a non-owning pointer, so // copying is most efficient.
// Construct/assign from a T* raw pointer. // A raw pointer should usually point at a valid object, however we want to // leave the ability to the user to create a NonDereferenceable from any // pointer. Also, strictly speaking, in a constructor or destructor, `this` // points at an object still being constructed or already partially // destructed, which some very sensitive sanitizers could complain about.
NO_POINTEE_CHECKS explicit NonDereferenceable(T* aPtr) : mPtr(aPtr) {}
NO_POINTEE_CHECKS
NonDereferenceable& operator=(T* aPtr) {
mPtr = aPtr; return *this;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.