summaryrefslogtreecommitdiff
path: root/libcxx/test/support/test_macros.h
blob: cde783a41db7edd068a96626665f6c38da53b8b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef SUPPORT_TEST_MACROS_HPP
#define SUPPORT_TEST_MACROS_HPP

// Attempt to get STL specific macros like _LIBCPP_VERSION using the most
// minimal header possible. If we're testing libc++, we should use `<__config>`.
// If <__config> isn't available, fall back to <ciso646>.
#ifdef __has_include
# if __has_include("<__config>")
#   include <__config>
#   define TEST_IMP_INCLUDED_HEADER
# endif
#endif
#ifndef TEST_IMP_INCLUDED_HEADER
#include <ciso646>
#endif

#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvariadic-macros"
#endif

#define TEST_STRINGIZE_IMPL(x) #x
#define TEST_STRINGIZE(x) TEST_STRINGIZE_IMPL(x)

#define TEST_CONCAT1(X, Y) X##Y
#define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y)

#ifdef __has_feature
#define TEST_HAS_FEATURE(X) __has_feature(X)
#else
#define TEST_HAS_FEATURE(X) 0
#endif

#ifndef __has_include
#define __has_include(...) 0
#endif

#ifdef __has_extension
#define TEST_HAS_EXTENSION(X) __has_extension(X)
#else
#define TEST_HAS_EXTENSION(X) 0
#endif

#ifdef __has_warning
#define TEST_HAS_WARNING(X) __has_warning(X)
#else
#define TEST_HAS_WARNING(X) 0
#endif

#ifdef __has_builtin
#define TEST_HAS_BUILTIN(X) __has_builtin(X)
#else
#define TEST_HAS_BUILTIN(X) 0
#endif
#ifdef __is_identifier
// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by
// the compiler and '1' otherwise.
#define TEST_HAS_BUILTIN_IDENTIFIER(X) !__is_identifier(X)
#else
#define TEST_HAS_BUILTIN_IDENTIFIER(X) 0
#endif

#if defined(__EDG__)
# define TEST_COMPILER_EDG
#elif defined(__clang__)
# define TEST_COMPILER_CLANG
# if defined(__apple_build_version__)
#  define TEST_COMPILER_APPLE_CLANG
# endif
#elif defined(_MSC_VER)
# define TEST_COMPILER_C1XX
#elif defined(__GNUC__)
# define TEST_COMPILER_GCC
#endif

#if defined(__apple_build_version__)
#define TEST_APPLE_CLANG_VER (__clang_major__ * 100) + __clang_minor__
#elif defined(__clang_major__)
#define TEST_CLANG_VER (__clang_major__ * 100) + __clang_minor__
#elif defined(__GNUC__)
// Given GCC XX.YY.ZZ, TEST_GCC_VER is XXYYZZ
#define TEST_GCC_VER ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__)
#endif

/* Make a nice name for the standard version */
#ifndef TEST_STD_VER
#if  __cplusplus <= 199711L
# define TEST_STD_VER 3
#elif __cplusplus <= 201103L
# define TEST_STD_VER 11
#elif __cplusplus <= 201402L
# define TEST_STD_VER 14
#elif __cplusplus <= 201703L
# define TEST_STD_VER 17
#elif __cplusplus <= 202002L
# define TEST_STD_VER 20
#else
# define TEST_STD_VER 99    // greater than current standard
// This is deliberately different than _LIBCPP_STD_VER to discourage matching them up.
#endif
#endif

// Attempt to deduce the GLIBC version
#if (defined(__has_include) && __has_include(<features.h>)) || \
    defined(__linux__)
#include <features.h>
#if defined(__GLIBC_PREREQ)
#define TEST_HAS_GLIBC
#define TEST_GLIBC_PREREQ(major, minor) __GLIBC_PREREQ(major, minor)
#endif
#endif

#if TEST_STD_VER >= 11
# define TEST_ALIGNOF(...) alignof(__VA_ARGS__)
# define TEST_ALIGNAS(...) alignas(__VA_ARGS__)
# define TEST_CONSTEXPR constexpr
# define TEST_NOEXCEPT noexcept
# define TEST_NOEXCEPT_FALSE noexcept(false)
# define TEST_NOEXCEPT_COND(...) noexcept(__VA_ARGS__)
#else
#   if defined(TEST_COMPILER_CLANG)
#    define TEST_ALIGNOF(...) _Alignof(__VA_ARGS__)
#   else
#    define TEST_ALIGNOF(...) __alignof(__VA_ARGS__)
#   endif
# define TEST_ALIGNAS(...) __attribute__((__aligned__(__VA_ARGS__)))
# define TEST_CONSTEXPR
# define TEST_NOEXCEPT throw()
# define TEST_NOEXCEPT_FALSE
# define TEST_NOEXCEPT_COND(...)
#endif

#if TEST_STD_VER >= 11
# define TEST_THROW_SPEC(...)
#else
# define TEST_THROW_SPEC(...) throw(__VA_ARGS__)
#endif

#if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
# define TEST_IS_CONSTANT_EVALUATED std::is_constant_evaluated()
#elif __has_builtin(__builtin_is_constant_evaluated)
# define TEST_IS_CONSTANT_EVALUATED __builtin_is_constant_evaluated()
#else
# define TEST_IS_CONSTANT_EVALUATED false
#endif

#if TEST_STD_VER >= 14
# define TEST_CONSTEXPR_CXX14 constexpr
#else
# define TEST_CONSTEXPR_CXX14
#endif

#if TEST_STD_VER >= 17
# define TEST_CONSTEXPR_CXX17 constexpr
#else
# define TEST_CONSTEXPR_CXX17
#endif

#if TEST_STD_VER >= 20
# define TEST_CONSTEXPR_CXX20 constexpr
#else
# define TEST_CONSTEXPR_CXX20
#endif

#define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__))

#if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \
    && !defined(__GXX_RTTI)
#define TEST_HAS_NO_RTTI
#endif

#if !defined(TEST_HAS_NO_RTTI)
# define RTTI_ASSERT(X) assert(X)
#else
# define RTTI_ASSERT(X)
#endif

#if !TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cpp_exceptions) \
     && !defined(__EXCEPTIONS)
#define TEST_HAS_NO_EXCEPTIONS
#endif

#if TEST_HAS_FEATURE(address_sanitizer) || TEST_HAS_FEATURE(memory_sanitizer) || \
    TEST_HAS_FEATURE(thread_sanitizer)
#define TEST_HAS_SANITIZERS
#endif

#if defined(_LIBCPP_NORETURN)
#define TEST_NORETURN _LIBCPP_NORETURN
#else
#define TEST_NORETURN [[noreturn]]
#endif

#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \
  (!(TEST_STD_VER > 14 || \
    (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606L)))
#define TEST_HAS_NO_ALIGNED_ALLOCATION
#endif

#if defined(_LIBCPP_SAFE_STATIC)
#define TEST_SAFE_STATIC _LIBCPP_SAFE_STATIC
#else
#define TEST_SAFE_STATIC
#endif

#if !defined(__cpp_impl_three_way_comparison) \
    && (!defined(_MSC_VER) || defined(__clang__) || _MSC_VER < 1920 || _MSVC_LANG <= 201703L)
#define TEST_HAS_NO_SPACESHIP_OPERATOR
#endif

#if TEST_STD_VER < 11
#define ASSERT_NOEXCEPT(...)
#define ASSERT_NOT_NOEXCEPT(...)
#else
#define ASSERT_NOEXCEPT(...) \
    static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept")

#define ASSERT_NOT_NOEXCEPT(...) \
    static_assert(!noexcept(__VA_ARGS__), "Operation must NOT be noexcept")
#endif

/* Macros for testing libc++ specific behavior and extensions */
#if defined(_LIBCPP_VERSION)
#define LIBCPP_ASSERT(...) assert(__VA_ARGS__)
#define LIBCPP_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
#define LIBCPP_ASSERT_NOEXCEPT(...) ASSERT_NOEXCEPT(__VA_ARGS__)
#define LIBCPP_ASSERT_NOT_NOEXCEPT(...) ASSERT_NOT_NOEXCEPT(__VA_ARGS__)
#define LIBCPP_ONLY(...) __VA_ARGS__
#else
#define LIBCPP_ASSERT(...) static_assert(true, "")
#define LIBCPP_STATIC_ASSERT(...) static_assert(true, "")
#define LIBCPP_ASSERT_NOEXCEPT(...) static_assert(true, "")
#define LIBCPP_ASSERT_NOT_NOEXCEPT(...) static_assert(true, "")
#define LIBCPP_ONLY(...) static_assert(true, "")
#endif

#if !defined(_LIBCPP_HAS_NO_RANGES)
#define TEST_SUPPORTS_RANGES
#endif

#define TEST_IGNORE_NODISCARD (void)

namespace test_macros_detail {
template <class T, class U>
struct is_same { enum { value = 0};} ;
template <class T>
struct is_same<T, T> { enum {value = 1}; };
} // namespace test_macros_detail

#define ASSERT_SAME_TYPE(...) \
    static_assert((test_macros_detail::is_same<__VA_ARGS__>::value), \
                 "Types differ unexpectedly")

#ifndef TEST_HAS_NO_EXCEPTIONS
#define TEST_THROW(...) throw __VA_ARGS__
#else
#if defined(__GNUC__)
#define TEST_THROW(...) __builtin_abort()
#else
#include <stdlib.h>
#define TEST_THROW(...) ::abort()
#endif
#endif

#if defined(__GNUC__) || defined(__clang__)
template <class Tp>
inline
void DoNotOptimize(Tp const& value) {
    asm volatile("" : : "r,m"(value) : "memory");
}

template <class Tp>
inline void DoNotOptimize(Tp& value) {
#if defined(__clang__)
  asm volatile("" : "+r,m"(value) : : "memory");
#else
  asm volatile("" : "+m,r"(value) : : "memory");
#endif
}
#else
#include <intrin.h>
template <class Tp>
inline void DoNotOptimize(Tp const& value) {
  const volatile void* volatile unused = __builtin_addressof(value);
  static_cast<void>(unused);
  _ReadWriteBarrier();
}
#endif

#if defined(__GNUC__)
#define TEST_ALWAYS_INLINE __attribute__((always_inline))
#define TEST_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
#define TEST_ALWAYS_INLINE __forceinline
#define TEST_NOINLINE __declspec(noinline)
#else
#define TEST_ALWAYS_INLINE
#define TEST_NOINLINE
#endif

#ifdef _WIN32
#define TEST_NOT_WIN32(...) ((void)0)
#else
#define TEST_NOT_WIN32(...) __VA_ARGS__
#endif

#if (defined(_WIN32) && !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)) ||   \
    defined(__MVS__)
// Macros for waiving cases when we can't count allocations done within
// the library implementation.
//
// On Windows, when libc++ is built as a DLL, references to operator new/delete
// within the DLL are bound at link time to the operator new/delete within
// the library; replacing them in the user executable doesn't override the
// calls within the library.
//
// The same goes on IBM zOS.
#define ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(...) ((void)(__VA_ARGS__))
#define TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS 0
#else
#define ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(...) assert(__VA_ARGS__)
#define TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS 1
#endif

#if (defined(_WIN32) && !defined(_MSC_VER) &&                                  \
     !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)) ||                      \
    defined(__MVS__)
// Normally, a replaced e.g. 'operator new' ends up used if the user code
// does a call to e.g. 'operator new[]'; it's enough to replace the base
// versions and have it override all of them.
//
// When the fallback operators are located within the libc++ library and we
// can't override the calls within it (see above), this fallback mechanism
// doesn't work either.
//
// On Windows, when using the MSVC vcruntime, the operator new/delete fallbacks
// are linked separately from the libc++ library, linked statically into
// the end user executable, and these fallbacks work even in DLL configurations.
// In MinGW configurations when built as a DLL, and on zOS, these fallbacks
// don't work though.
#define ASSERT_WITH_OPERATOR_NEW_FALLBACKS(...) ((void)(__VA_ARGS__))
#else
#define ASSERT_WITH_OPERATOR_NEW_FALLBACKS(...) assert(__VA_ARGS__)
#endif

#ifdef _WIN32
#define TEST_WIN_NO_FILESYSTEM_PERMS_NONE
#endif

// Support for carving out parts of the test suite, like removing wide characters, etc.
#if defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
#   define TEST_HAS_NO_WIDE_CHARACTERS
#endif

#if defined(_LIBCPP_HAS_NO_UNICODE)
#   define TEST_HAS_NO_UNICODE
#elif defined(_MSVC_EXECUTION_CHARACTER_SET) && _MSVC_EXECUTION_CHARACTER_SET != 65001
#   define TEST_HAS_NO_UNICODE
#endif

#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

#endif // SUPPORT_TEST_MACROS_HPP