Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 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
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>

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

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

static_assert(traps_<int> == _Integer_zero_division_traps,
"integer trap behavior should match the expectation from the current platform and complier");

static_assert(traps_<char> == traps_<int> && traps_<signed char> == traps_<int> && traps_<unsigned char> == traps_<int>
&& traps_<short> == traps_<int> && traps_<unsigned short> == traps_<int>
Comment on lines +30 to +31
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frederick-vs-ja suggests these should not trap either, according to LWG-554 resolution interpretation.
I'm not sure.

&& traps_<unsigned int> == traps_<int> //
&& traps_<long> == traps_<int> && traps_<unsigned long> == traps_<int>
&& traps_<long long> == traps_<int> && traps_<unsigned long long> == traps_<int>,
"all 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_<float> && !traps_<double> && !traps_<long double>,
"floats don't trap because even if '/fp:except' is passed, it should be enabled at runtime");