LCOV - code coverage report
Current view: top level - mfbt - OperatorNewExtensions.h (source / functions) Hit Total Coverage
Test: output.info Lines: 3 3 100.0 %
Date: 2017-07-14 16:53:18 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /* A version of |operator new| that eschews mandatory null-checks. */
       8             : 
       9             : #ifndef mozilla_OperatorNewExtensions_h
      10             : #define mozilla_OperatorNewExtensions_h
      11             : 
      12             : #include "mozilla/Assertions.h"
      13             : 
      14             : // Credit goes to WebKit for this implementation, cf.
      15             : // https://bugs.webkit.org/show_bug.cgi?id=74676
      16             : namespace mozilla {
      17             : enum NotNullTag {
      18             :   KnownNotNull,
      19             : };
      20             : } // namespace mozilla
      21             : 
      22             : /*
      23             :  * The logic here is a little subtle.  [expr.new] states that if the allocation
      24             :  * function being called returns null, then object initialization must not be
      25             :  * done, and the entirety of the new expression must return null.  Non-throwing
      26             :  * (noexcept) functions are defined to return null to indicate failure.  The
      27             :  * standard placement operator new is defined in such a way, and so it requires
      28             :  * a null check, even when that null check would be extraneous.  Functions
      29             :  * declared without such a specification are defined to throw std::bad_alloc if
      30             :  * they fail, and return a non-null pointer otherwise.  We compile without
      31             :  * exceptions, so any placement new overload we define that doesn't declare
      32             :  * itself as noexcept must therefore avoid generating a null check.  Below is
      33             :  * just such an overload.
      34             :  *
      35             :  * You might think that MOZ_NONNULL might perform the same function, but
      36             :  * MOZ_NONNULL isn't supported on all of our compilers, and even when it is
      37             :  * supported, doesn't work on all the versions we support.  And even keeping
      38             :  * those limitations in mind, we can't put MOZ_NONNULL on the global,
      39             :  * standardized placement new function in any event.
      40             :  *
      41             :  * We deliberately don't add MOZ_NONNULL(3) to tag |p| as non-null, to benefit
      42             :  * hypothetical static analyzers.  Doing so makes |MOZ_ASSERT(p)|'s internal
      43             :  * test vacuous, and some compilers warn about such vacuous tests.
      44             :  */
      45             : inline void*
      46     2646002 : operator new(size_t, mozilla::NotNullTag, void* p)
      47             : {
      48     2646002 :   MOZ_ASSERT(p);
      49     2646002 :   return p;
      50             : }
      51             : 
      52             : #endif // mozilla_OperatorNewExtensions_h

Generated by: LCOV version 1.13