aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-09-03 20:11:43 +0200
committerJakub Jelinek <jakub@redhat.com>2020-09-03 20:11:43 +0200
commit6641d6d3fe79113f8d9f3ced355aea79bffda822 (patch)
tree17816f5c34c8176c1c30bf7eb28180e5c36c9d83 /gcc/cp/constexpr.c
parent032a4b42cc5f2105f622690ce2552f1c30e1d227 (diff)
downloadgcc-6641d6d3fe79113f8d9f3ced355aea79bffda822.zip
gcc-6641d6d3fe79113f8d9f3ced355aea79bffda822.tar.gz
gcc-6641d6d3fe79113f8d9f3ced355aea79bffda822.tar.bz2
c++: Disable -frounding-math during manifestly constant evaluation [PR96862]
As discussed in the PR, fold-const.c punts on floating point constant evaluation if the result is inexact and -frounding-math is turned on. /* Don't constant fold this floating point operation if the result may dependent upon the run-time rounding mode and flag_rounding_math is set, or if GCC's software emulation is unable to accurately represent the result. */ if ((flag_rounding_math || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations)) && (inexact || !real_identical (&result, &value))) return NULL_TREE; Jonathan said that we should be evaluating them anyway, e.g. conceptually as if they are done with the default rounding mode before user had a chance to change that, and e.g. in C in initializers it is also ignored. In fact, fold-const.c for C initializers turns off various other options: /* Perform constant folding and related simplification of initializer expression EXPR. These behave identically to "fold_buildN" but ignore potential run-time traps and exceptions that fold must preserve. */ int saved_signaling_nans = flag_signaling_nans;\ int saved_trapping_math = flag_trapping_math;\ int saved_rounding_math = flag_rounding_math;\ int saved_trapv = flag_trapv;\ int saved_folding_initializer = folding_initializer;\ flag_signaling_nans = 0;\ flag_trapping_math = 0;\ flag_rounding_math = 0;\ flag_trapv = 0;\ folding_initializer = 1; flag_signaling_nans = saved_signaling_nans;\ flag_trapping_math = saved_trapping_math;\ flag_rounding_math = saved_rounding_math;\ flag_trapv = saved_trapv;\ folding_initializer = saved_folding_initializer; So, shall cxx_eval_outermost_constant_expr instead turn off all those options (then warning_sentinel wouldn't be the right thing to use, but given the 8 or how many return stmts in cxx_eval_outermost_constant_expr, we'd need a RAII class for this. Not sure about the folding_initializer, that one is affecting complex multiplication and division constant evaluation somehow. 2020-09-03 Jakub Jelinek <jakub@redhat.com> PR c++/96862 * constexpr.c (cxx_eval_outermost_constant_expr): Temporarily disable flag_rounding_math during manifestly constant evaluation. * g++.dg/cpp1z/constexpr-96862.C: New test.
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 8ee0f2a..2a5051c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -6680,6 +6680,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
allow_non_constant, strict,
manifestly_const_eval || !allow_non_constant };
+ /* Turn off -frounding-math for manifestly constant evaluation. */
+ warning_sentinel rm (flag_rounding_math, ctx.manifestly_const_eval);
tree type = initialized_type (t);
tree r = t;
bool is_consteval = false;