Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2b4fb31
Integer coverage
AlexGuteniev Oct 28, 2025
9833a4a
Product code fix
AlexGuteniev Oct 28, 2025
b17606a
Skip numeric.limits.members/traps.pass.cpp for Clang.
AlexGuteniev Oct 28, 2025
97e6faa
Skippy skip
AlexGuteniev Oct 28, 2025
586b09f
Merge remote-tracking branch 'upstream/main' into tricks-and-traps
AlexGuteniev Oct 29, 2025
e627022
it is always the trap
AlexGuteniev Oct 30, 2025
ad6a32f
but Clang
AlexGuteniev Oct 30, 2025
816d158
concise override
AlexGuteniev Oct 30, 2025
6996605
Spell that more naturally
AlexGuteniev Oct 30, 2025
3347a99
Now we know
AlexGuteniev Oct 30, 2025
a49bce3
comprehensive compile-time coverage
AlexGuteniev Oct 30, 2025
e1a996e
nicer test format
AlexGuteniev Oct 30, 2025
257f831
No longer SKIPPED actually
AlexGuteniev Oct 30, 2025
4ede9b1
No more death, no more execution!
AlexGuteniev Nov 2, 2025
72bd6f4
spelling
AlexGuteniev Nov 2, 2025
614a323
spelling
AlexGuteniev Nov 2, 2025
c9c5ab7
ARM64EC fix
AlexGuteniev Nov 2, 2025
1c3179e
back 2 skipped
AlexGuteniev Nov 2, 2025
6e2f0e9
Merge branch 'main' into tricks-and-traps
AlexGuteniev Nov 6, 2025
b0fa9a6
mention LWG-554
AlexGuteniev Nov 6, 2025
db1c4c7
promoted integers don't trap
AlexGuteniev Nov 15, 2025
1354e26
missing wchar_t
AlexGuteniev Nov 15, 2025
870d8ee
missing short
AlexGuteniev Nov 15, 2025
a10866e
Avoid variable and comments
AlexGuteniev Nov 15, 2025
b60b033
unnecessary transitivity
AlexGuteniev Nov 15, 2025
a9ae3eb
even fewer comments
AlexGuteniev Nov 15, 2025
2c6a27b
Merge branch 'main' into tricks-and-traps
AlexGuteniev Nov 16, 2025
167deb4
Don't trap on promoted uint32_t
AlexGuteniev Nov 16, 2025
6780f4c
elaborate
AlexGuteniev Nov 16, 2025
a6936c2
backwards
AlexGuteniev Nov 16, 2025
44ef94f
don't binary negate bool
AlexGuteniev Nov 16, 2025
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
15 changes: 14 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 @@ -444,6 +453,7 @@ public:
}

static constexpr bool is_modulo = true;
static constexpr bool traps = false;
static constexpr int digits = 32;
static constexpr int digits10 = 9;
};
Expand Down Expand Up @@ -488,6 +498,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 +543,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 +722,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 @@ -273,6 +273,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,51 @@
// 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. "
"These are translated to STATUS_INTEGER_DIVIDE_BY_ZERO and STATUS_INTEGER_OVERFLOW 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

template <class T>
constexpr bool non_promoted_and_traps_if_int_does = std::is_same_v<decltype(~T{}), T> && traps_<T> == traps_<int>;

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

template <class T>
constexpr bool promoted_and_does_not_trap = !std::is_same_v<decltype(~T{}), T> && !traps_<T>;

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

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

#ifdef __cpp_char8_t
static_assert(
promoted_and_does_not_trap<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");