1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ASSERT
11#define _LIBCPP___ASSERT
12
13#include <__assertion_handler> // Note: this include is generated by CMake and is potentially vendor-provided.
14#include <__config>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20#define _LIBCPP_ASSERT(expression, message) \
21 (__builtin_expect(static_cast<bool>(expression), 1) \
22 ? (void)0 \
23 : _LIBCPP_ASSERTION_HANDLER(__FILE_NAME__ ":" _LIBCPP_TOSTRING( \
24 __LINE__) ": libc++ Hardening assertion " _LIBCPP_TOSTRING(expression) " failed: " message "\n"))
25
26// clang-format off
27// Fast hardening mode checks.
28
29#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
30
31// Enabled checks.
32# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
33# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
34// Disabled checks.
35// On most modern platforms, dereferencing a null pointer does not lead to an actual memory access.
36# define _LIBCPP_ASSERT_NON_NULL(expression, message) ((void)0)
37// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security
38// vulnerability.
39# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) ((void)0)
40# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) ((void)0)
41# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) ((void)0)
42# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) ((void)0)
43# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) ((void)0)
44# define _LIBCPP_ASSERT_PEDANTIC(expression, message) ((void)0)
45# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0)
46# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0)
47# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) ((void)0)
48
49// Extensive hardening mode checks.
50
51#elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
52
53// Enabled checks.
54# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
55# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
56# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message)
57# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
58# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message)
59# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message)
60# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
61# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message)
62# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message)
63# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
64// Disabled checks.
65# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0)
66# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0)
67
68// Debug hardening mode checks.
69
70#elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
71
72// All checks enabled.
73# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
74# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
75# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message)
76# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
77# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message)
78# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message)
79# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
80# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message)
81# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message)
82# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSERT(expression, message)
83# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
84# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
85
86// Disable all checks if hardening is not enabled.
87
88#else
89
90// All checks disabled.
91# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) ((void)0)
92# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) ((void)0)
93# define _LIBCPP_ASSERT_NON_NULL(expression, message) ((void)0)
94# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) ((void)0)
95# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) ((void)0)
96# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) ((void)0)
97# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) ((void)0)
98# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) ((void)0)
99# define _LIBCPP_ASSERT_PEDANTIC(expression, message) ((void)0)
100# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0)
101# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0)
102# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) ((void)0)
103
104#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
105// clang-format on
106
107#endif // _LIBCPP___ASSERT
108