From: Jonathan Wakely Date: Wed, 3 May 2023 20:40:01 +0000 (+0100) Subject: libstdc++: Ensure constexpr std::lcm detects out-of-range result [PR105844] X-Git-Tag: releases/gcc-10.5.0~103 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b357af31b8d1e93f0f70133e25d3ad4045f7a32b;p=thirdparty%2Fgcc.git 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. --- 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" }