1f87aa19bSLouis Dionne// -*- C++ -*- 2f87aa19bSLouis Dionne//===----------------------------------------------------------------------===// 3f87aa19bSLouis Dionne// 4f87aa19bSLouis Dionne// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5f87aa19bSLouis Dionne// See https://llvm.org/LICENSE.txt for license information. 6f87aa19bSLouis Dionne// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7f87aa19bSLouis Dionne// 8f87aa19bSLouis Dionne//===----------------------------------------------------------------------===// 9f87aa19bSLouis Dionne 10f87aa19bSLouis Dionne#ifndef _LIBCPP___ASSERT 11f87aa19bSLouis Dionne#define _LIBCPP___ASSERT 12f87aa19bSLouis Dionne 138dfc67d6SKonstantin Varlamov#include <__assertion_handler> // Note: this include is generated by CMake and is potentially vendor-provided. 14f87aa19bSLouis Dionne#include <__config> 15f87aa19bSLouis Dionne 16f87aa19bSLouis Dionne#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 17f87aa19bSLouis Dionne# pragma GCC system_header 18f87aa19bSLouis Dionne#endif 19f87aa19bSLouis Dionne 20f0799465SLouis Dionne#define _LIBCPP_ASSERT(expression, message) \ 218c718dc9SLouis Dionne (__builtin_expect(static_cast<bool>(expression), 1) \ 228c718dc9SLouis Dionne ? (void)0 \ 238dfc67d6SKonstantin Varlamov : _LIBCPP_ASSERTION_HANDLER(__FILE__ ":" _LIBCPP_TOSTRING(__LINE__) ": assertion " _LIBCPP_TOSTRING( \ 248dfc67d6SKonstantin Varlamov expression) " failed: " message "\n")) 25f0dfe682Svarconst 26*adeae925SDavid Benjamin// WARNING: __builtin_assume can currently inhibit optimizations. Only add assumptions with a clear 27*adeae925SDavid Benjamin// optimization intent. See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a 28*adeae925SDavid Benjamin// discussion. 29*adeae925SDavid Benjamin#if __has_builtin(__builtin_assume) 30f0dfe682Svarconst# define _LIBCPP_ASSUME(expression) \ 318c718dc9SLouis Dionne (_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \ 328c718dc9SLouis Dionne __builtin_assume(static_cast<bool>(expression)) _LIBCPP_DIAGNOSTIC_POP) 33f0799465SLouis Dionne#else 34f0dfe682Svarconst# define _LIBCPP_ASSUME(expression) ((void)0) 35f0799465SLouis Dionne#endif 36f87aa19bSLouis Dionne 3737dca605SLouis Dionne// clang-format off 3837dca605SLouis Dionne// Fast hardening mode checks. 3937dca605SLouis Dionne 4037dca605SLouis Dionne#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST 4137dca605SLouis Dionne 4237dca605SLouis Dionne// Enabled checks. 4337dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) 4437dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) 4537dca605SLouis Dionne// Disabled checks. 4637dca605SLouis Dionne// On most modern platforms, dereferencing a null pointer does not lead to an actual memory access. 47*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_NON_NULL(expression, message) ((void)0) 4837dca605SLouis Dionne// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security 4937dca605SLouis Dionne// vulnerability. 50*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) ((void)0) 51*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) ((void)0) 52*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) ((void)0) 53*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) ((void)0) 54*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) ((void)0) 55*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_PEDANTIC(expression, message) ((void)0) 56*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0) 57*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0) 58*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) ((void)0) 5937dca605SLouis Dionne 6037dca605SLouis Dionne// Extensive hardening mode checks. 6137dca605SLouis Dionne 6237dca605SLouis Dionne#elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE 6337dca605SLouis Dionne 6437dca605SLouis Dionne// Enabled checks. 6537dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) 6637dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) 6737dca605SLouis Dionne# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message) 6837dca605SLouis Dionne# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message) 6937dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message) 7037dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message) 7137dca605SLouis Dionne# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message) 7237dca605SLouis Dionne# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message) 7337dca605SLouis Dionne# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message) 7437dca605SLouis Dionne# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) 7537dca605SLouis Dionne// Disabled checks. 76*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0) 77*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0) 7837dca605SLouis Dionne 7937dca605SLouis Dionne// Debug hardening mode checks. 8037dca605SLouis Dionne 8137dca605SLouis Dionne#elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG 8237dca605SLouis Dionne 8337dca605SLouis Dionne// All checks enabled. 8437dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) 8537dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) 8637dca605SLouis Dionne# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message) 8737dca605SLouis Dionne# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message) 8837dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message) 8937dca605SLouis Dionne# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message) 9037dca605SLouis Dionne# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message) 9137dca605SLouis Dionne# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message) 9237dca605SLouis Dionne# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message) 9337dca605SLouis Dionne# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSERT(expression, message) 9437dca605SLouis Dionne# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message) 9537dca605SLouis Dionne# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) 9637dca605SLouis Dionne 9737dca605SLouis Dionne// Disable all checks if hardening is not enabled. 9837dca605SLouis Dionne 9937dca605SLouis Dionne#else 10037dca605SLouis Dionne 10137dca605SLouis Dionne// All checks disabled. 102*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) ((void)0) 103*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) ((void)0) 104*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_NON_NULL(expression, message) ((void)0) 105*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) ((void)0) 106*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) ((void)0) 107*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) ((void)0) 108*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) ((void)0) 109*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) ((void)0) 110*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_PEDANTIC(expression, message) ((void)0) 111*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0) 112*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0) 113*adeae925SDavid Benjamin# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) ((void)0) 11437dca605SLouis Dionne 11537dca605SLouis Dionne#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST 11637dca605SLouis Dionne// clang-format on 11737dca605SLouis Dionne 118f87aa19bSLouis Dionne#endif // _LIBCPP___ASSERT 119