91
91
92
92
#define FLUX_DECLVAL (...) ((static_cast <__VA_ARGS__(*)()noexcept >(nullptr ))())
93
93
94
- #ifdef __GNUC__
95
- #define FLUX_ALWAYS_INLINE [[gnu::always_inline]]
94
+ #if defined(__GNUC__)
95
+ # define FLUX_ALWAYS_INLINE [[gnu::always_inline]] inline
96
+ #elif defined(_MSC_VER)
97
+ # define FLUX_ALWAYS_INLINE __forceinline
96
98
#else
97
- #define FLUX_ALWAYS_INLINE
99
+ # define FLUX_ALWAYS_INLINE inline
98
100
#endif
99
101
100
102
#define FLUX_NO_UNIQUE_ADDRESS [[no_unique_address]]
124
126
#include < type_traits>
125
127
126
128
#define FLUX_ERROR_POLICY_TERMINATE 1
127
- #define FLUX_ERROR_POLICY_UNWIND 2
129
+ #define FLUX_ERROR_POLICY_UNWIND 2
130
+ #define FLUX_ERROR_POLICY_FAIL_FAST 3
128
131
129
132
#define FLUX_OVERFLOW_POLICY_ERROR 10
130
133
#define FLUX_OVERFLOW_POLICY_WRAP 11
158
161
# define FLUX_ERROR_POLICY FLUX_ERROR_POLICY_TERMINATE
159
162
#elif defined(FLUX_UNWIND_ON_ERROR)
160
163
# define FLUX_ERROR_POLICY FLUX_ERROR_POLICY_UNWIND
164
+ #elif defined(FLUX_FAIL_FAST_ON_ERROR)
165
+ # define FLUX_ERROR_POLICY FLUX_ERROR_POLICY_FAIL_FAST
161
166
#else
162
167
# define FLUX_ERROR_POLICY FLUX_DEFAULT_ERROR_POLICY
163
168
#endif // FLUX_TERMINATE_ON_ERROR
@@ -234,7 +239,8 @@ namespace flux {
234
239
FLUX_EXPORT
235
240
enum class error_policy {
236
241
terminate = FLUX_ERROR_POLICY_TERMINATE,
237
- unwind = FLUX_ERROR_POLICY_UNWIND
242
+ unwind = FLUX_ERROR_POLICY_UNWIND,
243
+ fail_fast = FLUX_ERROR_POLICY_FAIL_FAST
238
244
};
239
245
240
246
FLUX_EXPORT
@@ -294,6 +300,15 @@ inline constexpr bool enable_debug_asserts = FLUX_ENABLE_DEBUG_ASSERTS;
294
300
#include < stdexcept>
295
301
#include < type_traits>
296
302
303
+ #if defined(__has_builtin)
304
+ # if __has_builtin(__builtin_trap)
305
+ # define FLUX_HAS_BUILTIN_TRAP 1
306
+ # endif
307
+ #elif defined(_MSC_VER)
308
+ # include < intrin.h>
309
+ # define FLUX_HAS_FASTFAIL 1
310
+ #endif
311
+
297
312
namespace flux {
298
313
299
314
FLUX_EXPORT
@@ -304,21 +319,51 @@ struct unrecoverable_error : std::logic_error {
304
319
namespace detail {
305
320
306
321
struct runtime_error_fn {
322
+ private:
323
+ [[noreturn]]
324
+ FLUX_ALWAYS_INLINE
325
+ static void fail_fast ()
326
+ {
327
+ #if FLUX_HAS_BUILTIN_TRAP
328
+ __builtin_trap ();
329
+ #elif FLUX_HAS_FASTFAIL
330
+ __fastfail (7 ); // FAST_FAIL_FATAL_APP_EXIT
331
+ #else
332
+ std::abort ();
333
+ #endif
334
+ }
335
+
307
336
[[noreturn]]
337
+ static void unwind (const char * msg, std::source_location loc)
338
+ {
339
+ char buf[1024 ];
340
+ std::snprintf (buf, 1024 , " %s:%u: Fatal error: %s" ,
341
+ loc.file_name (), loc.line (), msg);
342
+ throw unrecoverable_error (buf);
343
+ }
344
+
345
+ [[noreturn]]
346
+ static void terminate (const char * msg, std::source_location loc)
347
+ {
348
+ if constexpr (config::print_error_on_terminate) {
349
+ std::fprintf (stderr, " %s:%u: Fatal error: %s\n " ,
350
+ loc.file_name (), loc.line (), msg);
351
+ }
352
+ std::terminate ();
353
+ }
354
+
355
+ public:
356
+ [[noreturn]]
357
+ FLUX_ALWAYS_INLINE
308
358
void operator ()(char const * msg,
309
359
std::source_location loc = std::source_location::current()) const
310
360
{
311
- if constexpr (config::on_error == error_policy::unwind) {
312
- char buf[1024 ];
313
- std::snprintf (buf, 1024 , " %s:%u: Fatal error: %s" ,
314
- loc.file_name (), loc.line (), msg);
315
- throw unrecoverable_error (buf);
361
+ if constexpr (config::on_error == error_policy::fail_fast) {
362
+ fail_fast ();
363
+ } else if constexpr (config::on_error == error_policy::unwind) {
364
+ unwind (msg, loc);
316
365
} else {
317
- if constexpr (config::print_error_on_terminate) {
318
- std::fprintf (stderr, " %s:%u: Fatal error: %s\n " ,
319
- loc.file_name (), loc.line (), msg);
320
- }
321
- std::terminate ();
366
+ terminate (msg, loc);
322
367
}
323
368
}
324
369
};
@@ -368,8 +413,7 @@ struct indexed_bounds_check_fn {
368
413
}
369
414
}
370
415
#endif
371
- assert_fn{}(idx >= T{0 }, " index cannot be negative" , loc);
372
- assert_fn{}(idx < limit, " out-of-bounds sequence access" , loc);
416
+ assert_fn{}(idx >= T{0 } && idx < limit, " out-of-bounds sequence access" , loc);
373
417
}
374
418
}
375
419
};
0 commit comments