From b357af31b8d1e93f0f70133e25d3ad4045f7a32b Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 3 May 2023 21:40:01 +0100 Subject: [PATCH] libstdc++: Ensure constexpr std::lcm detects out-of-range result [PR105844] On the gcc-10 branch, __glibcxx_assert does not unconditionally check the condition during constant evaluation. This means we need an explicit additional check for std::lcm results that cannot be represented in an unsigned result type. libstdc++-v3/ChangeLog: PR libstdc++/105844 * include/std/numeric (lcm): Ensure out-of-range result is detected in constant evaluation. * testsuite/26_numerics/lcm/105844.cc: Adjust dg-error string. --- libstdc++-v3/include/std/numeric | 5 +++++ libstdc++-v3/testsuite/26_numerics/lcm/105844.cc | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric index b81b5e4a30f4..f4636679223d 100644 --- a/libstdc++-v3/include/std/numeric +++ b/libstdc++-v3/include/std/numeric @@ -161,6 +161,11 @@ namespace __detail #endif bool __overflow = __builtin_mul_overflow(__r, __n2, &__r); +#if defined _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED + if (__builtin_is_constant_evaluated()) + if (__overflow) + _GLIBCXX_THROW_OR_ABORT("std::lcm result is out of range of type"); +#endif __glibcxx_assert(!__overflow); return __r; } diff --git a/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc b/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc index 0b5ef5ae5e90..c7338f3cbf39 100644 --- a/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc +++ b/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc @@ -19,6 +19,6 @@ constexpr int d = std::lcm(49999, 50000); // { dg-error "overflow" } // Similarly for unsigned, but the diagnostic is a failed assertion instead. constexpr int e = std::lcm(500000u, 499999); // { dg-error "in 'constexpr'" } constexpr int f = std::lcm(499999u, 500000); // { dg-error "in 'constexpr'" } -// { dg-error "unreachable" "" { target *-*-* } 0 } +// { dg-error "throw.* not a constant expression" "" { target *-*-* } 0 } // { dg-prune-output "in 'constexpr' expansion" } -- 2.47.2