Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion stl/inc/limits
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ struct _Num_int_base : _Num_base { // base for integer types
static constexpr bool is_exact = true;
static constexpr bool is_integer = true;
static constexpr bool is_specialized = true;
static constexpr int radix = 2;
#if !defined(__clang__) || defined(_M_X64) && !defined(_M_ARM64EC) || defined(_M_IX86)
static constexpr bool traps = true;
#endif
static constexpr int radix = 2;
};

struct _Num_float_base : _Num_base { // base for floating-point types
Expand Down Expand Up @@ -178,6 +181,7 @@ public:
return 0;
}

static constexpr bool traps = false;
static constexpr int digits = 1;
};

Expand Down Expand Up @@ -222,6 +226,7 @@ public:

static constexpr bool is_signed = CHAR_MIN != 0;
static constexpr bool is_modulo = CHAR_MIN == 0;
static constexpr bool traps = false;
static constexpr int digits = 8 - (CHAR_MIN != 0);
static constexpr int digits10 = 2;
};
Expand Down Expand Up @@ -266,6 +271,7 @@ public:
}

static constexpr bool is_signed = true;
static constexpr bool traps = false;
static constexpr int digits = 7;
static constexpr int digits10 = 2;
};
Expand Down Expand Up @@ -310,6 +316,7 @@ public:
}

static constexpr bool is_modulo = true;
static constexpr bool traps = false;
static constexpr int digits = 8;
static constexpr int digits10 = 2;
};
Expand Down Expand Up @@ -355,6 +362,7 @@ public:
}

static constexpr bool is_modulo = true;
static constexpr bool traps = false;
static constexpr int digits = 8;
static constexpr int digits10 = 2;
};
Expand Down Expand Up @@ -400,6 +408,7 @@ public:
}

static constexpr bool is_modulo = true;
static constexpr bool traps = false;
static constexpr int digits = 16;
static constexpr int digits10 = 4;
};
Expand Down Expand Up @@ -488,6 +497,7 @@ public:
}

static constexpr bool is_modulo = true;
static constexpr bool traps = false;
static constexpr int digits = 16;
static constexpr int digits10 = 4;
};
Expand Down Expand Up @@ -532,6 +542,7 @@ public:
}

static constexpr bool is_signed = true;
static constexpr bool traps = false;
static constexpr int digits = 15;
static constexpr int digits10 = 4;
};
Expand Down Expand Up @@ -710,6 +721,7 @@ public:
}

static constexpr bool is_modulo = true;
static constexpr bool traps = false;
static constexpr int digits = 16;
static constexpr int digits10 = 4;
};
Expand Down
14 changes: 9 additions & 5 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -733,11 +733,6 @@ std/depr/depr.c.headers/tgmath_h.pass.cpp:2 FAIL


# *** CLANG ISSUES, NOT YET ANALYZED ***
# Not analyzed. Clang apparently defines platform macros differently from C1XX.
# The test inspects `__x86_64__` and `__i386__`, which MSVC doesn't define.
# SKIPPED because this fails for x64/x86 and passes for ARM64.
std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp:2 SKIPPED

# Not analyzed. Possibly C++20 equality operator rewrite issues.
std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp:2 FAIL
std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp:2 FAIL
Expand Down Expand Up @@ -996,6 +991,15 @@ std/containers/sequences/vector/trivial_relocation.pass.cpp:1 FAIL
# Not analyzed, likely bogus test. constexpr fails with "vector iterators incompatible".
std/ranges/range.adaptors/range.join.with/range.join.with.iterator/ctor.default.pass.cpp FAIL

# Problems in this test:
# - Clang does not trap on Arm64, but MSVC does.
# - The test inspects `__x86_64__` and `__i386__`, which MSVC doesn't define.
# - The __x86_64__ is defined on ARM64EC, but it is expected to behave like ARM64
# :2 SKIPPED because this passes for x64/x86/ARM64 and fails for ARM64EC.
std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp:0 FAIL
std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp:1 FAIL
std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp:2 SKIPPED


# *** LIKELY STL BUGS ***
# Not analyzed, likely STL bugs. Various assertions.
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ tests\GH_005546_containers_size_type_cast
tests\GH_005553_regex_character_translation
tests\GH_005768_pow_accuracy
tests\GH_005800_stable_sort_large_alignment
tests\GH_005816_numeric_limits_traps
tests\LWG2381_num_get_floating_point
tests\LWG2510_tag_classes
tests\LWG2597_complex_branch_cut
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/GH_005816_numeric_limits_traps/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_matrix.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <limits>

template <class T>
constexpr bool traps_ = std::numeric_limits<T>::traps;

#if defined(_M_IX86) || defined(_M_X64) && !defined(_M_ARM64EC)
static_assert(traps_<int>,
"The #ED hardware exception always happens for zero division and for division overflow INT_MIN/-1. "
"It is translated to the corresponding SEH exceptions");
#elif defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64)
#ifdef __clang__
static_assert(!traps_<int>, "The hardware does not trap. Clang compiles code as is, so there's no trap");
#else // ^^^ defined(__clang__) / !defined(__clang__) vvv
static_assert(traps_<int>, "The hardware does not trap. MSVC inserts check for zero to trap zero division. "
"It does not insert checks for INT_MIN/-1 division overflow though");
#endif // ^^^ !defined(__clang__) ^^^
#else // ^^^ defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64) ^^^
#error Unsupported hardware
#endif

static_assert(traps_<unsigned int> == traps_<int> && traps_<char32_t> == traps_<int> //
&& traps_<long> == traps_<int> && traps_<unsigned long> == traps_<int>
&& traps_<long long> == traps_<int> && traps_<unsigned long long> == traps_<int>,
"all non-promoted integers should trap or not trap equally");

static_assert(!traps_<bool>, "bool does not trap for a moot reason; see LWG-554 resolution");

static_assert(!traps_<char> && !traps_<signed char> && !traps_<unsigned char> //
&& !traps_<short> && !traps_<unsigned short> && !traps_<wchar_t> && !traps_<char16_t>,
"promoted integers do not trap for a moot reason; see LWG-554 resolution");

#ifdef __cpp_char8_t
static_assert(!traps_<char8_t>, "promoted integers do not trap for a moot reason; see LWG-554 resolution");
#endif

static_assert(!traps_<float> && !traps_<double> && !traps_<long double>,
"floats don't trap because even if '/fp:except' is passed, it should be enabled at runtime");