|
17 | 17 | # pragma GCC system_header
|
18 | 18 | #endif
|
19 | 19 |
|
| 20 | +_LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | + |
| 22 | +_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int |
| 23 | +__assertion_failed_during_constant_evaluation(bool __value, const char*) _NOEXCEPT { |
| 24 | + return __value ? 0 : (__builtin_unreachable(), 0); |
| 25 | +} |
| 26 | + |
| 27 | +_LIBCPP_END_NAMESPACE_STD |
| 28 | + |
| 29 | +#define _LIBCPP_ASSERT_IS_CONSTANT_EVALUATED \ |
| 30 | + (_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wconstant-evaluated") __builtin_is_constant_evaluated() \ |
| 31 | + _LIBCPP_DIAGNOSTIC_POP) |
| 32 | + |
| 33 | +#define _LIBCPP_ASSERTTION_MESSAGE(__message) \ |
| 34 | + __FILE__ ":" _LIBCPP_TOSTRING(__LINE__) ": assertion " _LIBCPP_TOSTRING(expression) " failed: " __message "\n" |
| 35 | + |
20 | 36 | #define _LIBCPP_ASSERT(expression, message) \
|
21 |
| - (__builtin_expect(static_cast<bool>(expression), 1) \ |
22 |
| - ? (void)0 \ |
23 |
| - : _LIBCPP_ASSERTION_HANDLER(__FILE__ ":" _LIBCPP_TOSTRING(__LINE__) ": assertion " _LIBCPP_TOSTRING( \ |
24 |
| - expression) " failed: " message "\n")) |
| 37 | + (__builtin_expect(static_cast<bool>(expression), 1) ? (void)0 \ |
| 38 | + : _LIBCPP_ASSERT_IS_CONSTANT_EVALUATED \ |
| 39 | + ? (void)__assertion_failed_during_constant_evaluation(false, _LIBCPP_ASSERTTION_MESSAGE(message)) \ |
| 40 | + : _LIBCPP_ASSERTION_HANDLER(_LIBCPP_ASSERTTION_MESSAGE(message))) |
25 | 41 |
|
26 | 42 | // TODO: __builtin_assume can currently inhibit optimizations. Until this has been fixed and we can add
|
27 | 43 | // assumptions without a clear optimization intent, disable that to avoid worsening the code generation.
|
28 | 44 | // See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a discussion.
|
29 | 45 | #if 0 && __has_builtin(__builtin_assume)
|
30 |
| -# define _LIBCPP_ASSUME(expression) \ |
| 46 | +# define _LIBCPP_RUNTIME_ASSUME(expression) \ |
31 | 47 | (_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \
|
32 | 48 | __builtin_assume(static_cast<bool>(expression)) _LIBCPP_DIAGNOSTIC_POP)
|
33 | 49 | #else
|
34 |
| -# define _LIBCPP_ASSUME(expression) ((void)0) |
| 50 | +# define _LIBCPP_RUNTIME_ASSUME(expression) ((void)0) |
35 | 51 | #endif
|
36 | 52 |
|
| 53 | +#define _LIBCPP_ASSUME(expression, message) \ |
| 54 | + (_LIBCPP_ASSERT_IS_CONSTANT_EVALUATED \ |
| 55 | + ? (void)__assertion_failed_during_constant_evaluation( \ |
| 56 | + static_cast<bool>(expression), _LIBCPP_ASSERTTION_MESSAGE(message)) \ |
| 57 | + : _LIBCPP_RUNTIME_ASSUME(expression)) |
| 58 | + |
37 | 59 | // clang-format off
|
38 | 60 | // Fast hardening mode checks.
|
39 | 61 |
|
|
44 | 66 | # define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
|
45 | 67 | // Disabled checks.
|
46 | 68 | // On most modern platforms, dereferencing a null pointer does not lead to an actual memory access.
|
47 |
| -# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression) |
| 69 | +# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression, message) |
48 | 70 | // Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security
|
49 | 71 | // vulnerability.
|
50 |
| -# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression) |
51 |
| -# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression) |
52 |
| -# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression) |
53 |
| -# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) |
54 |
| -# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression) |
55 |
| -# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression) |
56 |
| -# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression) |
57 |
| -# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) |
58 |
| -# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) |
| 72 | +# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression, message) |
| 73 | +# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression, message) |
| 74 | +# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression, message) |
| 75 | +# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression, message) |
| 76 | +# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression, message) |
| 77 | +# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression, message) |
| 78 | +# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression, message) |
| 79 | +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression, message) |
| 80 | +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression, message) |
59 | 81 |
|
60 | 82 | // Extensive hardening mode checks.
|
61 | 83 |
|
|
73 | 95 | # define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message)
|
74 | 96 | # define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
|
75 | 97 | // Disabled checks.
|
76 |
| -# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression) |
77 |
| -# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) |
| 98 | +# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression, message) |
| 99 | +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression, message) |
78 | 100 |
|
79 | 101 | // Debug hardening mode checks.
|
80 | 102 |
|
|
99 | 121 | #else
|
100 | 122 |
|
101 | 123 | // All checks disabled.
|
102 |
| -# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression) |
103 |
| -# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression) |
104 |
| -# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression) |
105 |
| -# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression) |
106 |
| -# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression) |
107 |
| -# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression) |
108 |
| -# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) |
109 |
| -# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression) |
110 |
| -# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression) |
111 |
| -# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression) |
112 |
| -# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) |
113 |
| -# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) |
| 124 | +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression, message) |
| 125 | +# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression, message) |
| 126 | +# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression, message) |
| 127 | +# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression, message) |
| 128 | +# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression, message) |
| 129 | +# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression, message) |
| 130 | +# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression, message) |
| 131 | +# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression, message) |
| 132 | +# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression, message) |
| 133 | +# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression, message) |
| 134 | +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression, message) |
| 135 | +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression, message) |
114 | 136 |
|
115 | 137 | #endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
|
116 | 138 | // clang-format on
|
|
0 commit comments