Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/OperatorNewExtensions.h
Line
Count
Source
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
operator new(size_t, mozilla::NotNullTag, void* p)
47
142M
{
48
142M
  MOZ_ASSERT(p);
49
142M
  return p;
50
142M
}
51
52
#endif // mozilla_OperatorNewExtensions_h