33
44#include < limits>
55
6- #include < test_death.hpp>
7-
6+ #if defined(_M_IX86) || defined(_M_X64) && !defined(_M_ARM64EC)
7+ // The #ED hardware exception always happens for zero division and for division overflow INT_MIN/-1
8+ // It is translated to the corresponding SEH exxcptions
9+ constexpr bool _Integer_zero_division_traps = true ;
10+ #elif defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64)
11+ // The hardware does not trap.
812#ifdef __clang__
9- #pragma clang diagnostic ignored "-Wc++17-extensions" // constexpr if is a C++17 extension
13+ // Clang compiles code as is, so there's no trap
14+ constexpr bool _Integer_zero_division_traps = false ;
1015#else // ^^^ defined(__clang__) / !defined(__clang__) vvv
11- #pragma warning(disable : 4984) // warning C4984: 'if constexpr' is a C++17 language extension
16+ // MSVC inserts check for zero to trap zero division.
17+ // It does not insert thecks for INT_MIN/-1 division overflow though.
18+ constexpr bool _Integer_zero_division_traps = true ;
1219#endif // ^^^ !defined(__clang__) ^^^
20+ #else // ^^^ defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64) ^^^
21+ #error Unsupported hardware
22+ #endif
1323
1424template <class T >
1525constexpr bool traps_ = std::numeric_limits<T>::traps;
1626
17- static_assert (!traps_<bool >, " bool does not trap for a moot reason" );
18-
19- static_assert (!traps_<float > && !traps_<double > && !traps_<long double >,
20- " floats don't trap because even if '/fp:except' is passed, it should be enabled at runtime" );
27+ static_assert (traps_<int > == _Integer_zero_division_traps,
28+ " integer trap behavior should match the expectation from the current platform and complier" );
2129
2230static_assert (traps_<char > == traps_<int > && traps_<signed char > == traps_<int > && traps_<unsigned char > == traps_<int >
2331 && traps_<short > == traps_<int > && traps_<unsigned short > == traps_<int >
@@ -26,20 +34,7 @@ static_assert(traps_<char> == traps_<int> && traps_<signed char> == traps_<int>
2634 && traps_<long long > == traps_<int > && traps_<unsigned long long > == traps_<int >,
2735 " all integers should trap or not trap equally" );
2836
29- void trap_operation () {
30- const volatile int op1 = 1 ;
31- const volatile int op2 = 0 ;
32- const volatile int res = op1 / op2;
33- (void ) res;
34- }
37+ static_assert (!traps_<bool >, " bool does not trap for a moot reason" );
3538
36- int main (int argc, char * argv[]) {
37- if constexpr (traps_<int >) {
38- std_testing::death_test_executive exec;
39- const std_testing::death_function_t one_trap[] = {trap_operation};
40- exec.add_death_tests (one_trap);
41- return exec.run (argc, argv);
42- } else {
43- trap_operation ();
44- }
45- }
39+ static_assert (!traps_<float > && !traps_<double > && !traps_<long double >,
40+ " floats don't trap because even if '/fp:except' is passed, it should be enabled at runtime" );
0 commit comments