[NFC][Py Reformat] Reformat python files in libcxx/libcxxabi
[llvm-project.git] / libcxx / test / support / assert_macros.h
blobbf382e19d5e04ad53737dbc6d88dc93c68233397
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef TEST_SUPPORT_ASSERT_MACROS_H
10 #define TEST_SUPPORT_ASSERT_MACROS_H
12 // Contains a set of validation macros.
14 // Note these test were added after C++20 was well supported by the compilers
15 // used. To make the implementation simple the macros require C++20 or newer.
16 // It's not expected that existing tests start to use these new macros.
18 // These macros are an alternative to using assert. The differences are:
19 // - The assert message isn't localized.
20 // - It's possible to log additional information. This is useful when the
21 // function asserting is a helper function. In these cases the assertion
22 // failure contains to little information to find the issue. For example, in
23 // the format functions, the really useful information is the actual output,
24 // the expected output, and the format string used. These macros allow
25 // logging additional arguments.
27 #include "test_macros.h"
29 #include <cstdio>
30 #include <cstdlib>
32 // This function prints the given arguments to standard error.
34 // Keeping this as a separate function is important since it provides a single point for
35 // downstreams to customize how errors are printed on exotic targets, if needed.
36 template <class ...Args>
37 void test_eprintf(char const* fmt, Args const& ...args) {
38 std::fprintf(stderr, fmt, args...);
41 void test_log(const char* condition, const char* file, int line, const char* message) {
42 const char* msg = condition ? "Assertion failure: " : "Unconditional failure:";
43 test_eprintf("%s%s %s %d\n%s", msg, condition, file, line, message);
46 template <class F>
47 void test_log(const char* condition, const char* file, int line, const F& functor) {
48 test_eprintf("Assertion failure: %s %s %d\n", condition, file, line);
49 functor();
52 template <class Arg>
53 [[noreturn]] void test_fail(const char* file, int line, const Arg& arg) {
54 test_log("", file, line, arg);
55 std::abort();
58 template <class Arg>
59 void test_require(bool condition, const char* condition_str, const char* file, int line, const Arg& arg) {
60 if (condition)
61 return;
63 test_log(condition_str, file, line, arg);
64 std::abort();
67 // assert(false) replacement
68 // The ARG is either a
69 // - c-ctring or std::string, in which case the string is printed to stderr,
70 // - an invocable object, which will be invoked.
71 #define TEST_FAIL(ARG) ::test_fail(__FILE__, __LINE__, ARG)
73 // assert replacement.
74 // ARG is the same as for TEST_FAIL
75 #define TEST_REQUIRE(CONDITION, ARG) ::test_require(CONDITION, #CONDITION, __FILE__, __LINE__, ARG)
77 // LIBCPP_ASSERT replacement
79 // This requirement is only tested when the test suite is used for libc++.
80 // This allows checking libc++ specific requirements, for example the error
81 // messages of exceptions.
82 // ARG is the same as for TEST_FAIL
83 #if defined(_LIBCPP_VERSION)
84 # define TEST_LIBCPP_REQUIRE(CONDITION, ARG) ::test_require(CONDITION, #CONDITION, __FILE__, __LINE__, ARG)
85 #else
86 # define TEST_LIBCPP_REQUIRE(...) /* DO NOTHING */
87 #endif
89 // Helper macro to test an expression does not throw any exception.
90 #ifndef TEST_HAS_NO_EXCEPTIONS
91 # define TEST_DOES_NOT_THROW(EXPR) \
92 do { \
93 try { \
94 static_cast<void>(EXPR); \
95 } catch (...) { \
96 ::test_log(#EXPR, __FILE__, __LINE__, "no exception was expected\n"); \
97 ::std::abort(); \
98 } \
99 } while (false) /* */
101 // Helper macro to test an expression throws an exception of the expected type.
102 # define TEST_THROWS_TYPE(TYPE, EXPR) \
103 do { \
104 try { \
105 static_cast<void>(EXPR); \
106 ::test_log(nullptr, \
107 __FILE__, \
108 __LINE__, \
109 "no exception is thrown while an exception of type " #TYPE " was expected\n"); \
110 ::std::abort(); \
111 } catch (const TYPE&) { \
112 /* DO NOTHING */ \
113 } catch (...) { \
114 ::test_log(nullptr, \
115 __FILE__, \
116 __LINE__, \
117 "the type of the exception caught differs from the expected type " #TYPE "\n"); \
118 ::std::abort(); \
120 } while (false) /* */
122 // Helper macro to test an expression throws an exception of the expected type and satisfies a predicate.
124 // In order to log additional information the predicate can use log macros.
125 // The exception caught is used as argument to the predicate.
126 # define TEST_VALIDATE_EXCEPTION(TYPE, PRED, EXPR) \
127 do { \
128 try { \
129 static_cast<void>(EXPR); \
130 ::test_log(nullptr, \
131 __FILE__, \
132 __LINE__, \
133 "no exception is thrown while an exception of type " #TYPE " was expected\n"); \
134 ::std::abort(); \
135 } catch (const TYPE& EXCEPTION) { \
136 PRED(EXCEPTION); \
137 } catch (...) { \
138 ::test_log(nullptr, \
139 __FILE__, \
140 __LINE__, \
141 "the type of the exception caught differs from the expected type " #TYPE "\n"); \
142 ::std::abort(); \
144 } while (false) /* */
146 #else // TEST_HAS_NO_EXCEPTIONS
147 # define TEST_DOES_NOT_THROW(EXPR) static_cast<void>(EXPR);
148 # define TEST_THROWS_TYPE(...) /* DO NOTHING */
149 # define TEST_VALIDATE_EXCEPTION(...) /* DO NOTHING */
150 #endif // TEST_HAS_NO_EXCEPTIONS
152 #endif // TEST_SUPPORT_ASSERT_MACROS_H