From eec039211e396e35204b55588013d74289a984cd Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Thu, 8 Feb 2024 21:51:38 +0100 Subject: [PATCH] Fortran: error recovery on arithmetic overflow on unary operations [PR113799] PR fortran/113799 gcc/fortran/ChangeLog: * arith.cc (reduce_unary): Remember any overflow encountered during reduction of unary arithmetic operations on array constructors and continue, and return error status, but terminate on serious errors. gcc/testsuite/ChangeLog: * gfortran.dg/arithmetic_overflow_2.f90: New test. --- gcc/fortran/arith.cc | 11 ++++++++--- gcc/testsuite/gfortran.dg/arithmetic_overflow_2.f90 | 12 ++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/arithmetic_overflow_2.f90 diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc index 0598f6ac51b..d17d1aaa1d9 100644 --- a/gcc/fortran/arith.cc +++ b/gcc/fortran/arith.cc @@ -1323,6 +1323,7 @@ reduce_unary (arith (*eval) (gfc_expr *, gfc_expr **), gfc_expr *op, gfc_constructor *c; gfc_expr *r; arith rc; + bool ov = false; if (op->expr_type == EXPR_CONSTANT) return eval (op, result); @@ -1336,13 +1337,17 @@ reduce_unary (arith (*eval) (gfc_expr *, gfc_expr **), gfc_expr *op, { rc = reduce_unary (eval, c->expr, &r); - if (rc != ARITH_OK) + /* Remember any overflow encountered during reduction and continue, + but terminate on serious errors. */ + if (rc == ARITH_OVERFLOW) + ov = true; + else if (rc != ARITH_OK) break; gfc_replace_expr (c->expr, r); } - if (rc != ARITH_OK) + if (rc != ARITH_OK && rc != ARITH_OVERFLOW) gfc_constructor_free (head); else { @@ -1363,7 +1368,7 @@ reduce_unary (arith (*eval) (gfc_expr *, gfc_expr **), gfc_expr *op, *result = r; } - return rc; + return ov ? ARITH_OVERFLOW : rc; } diff --git a/gcc/testsuite/gfortran.dg/arithmetic_overflow_2.f90 b/gcc/testsuite/gfortran.dg/arithmetic_overflow_2.f90 new file mode 100644 index 00000000000..6ca27f74215 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/arithmetic_overflow_2.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! { dg-additional-options "-frange-check" } +! +! PR fortran/113799 - handle arithmetic overflow on unary minus + +program p + implicit none + real, parameter :: inf = real(z'7F800000') + real, parameter :: someInf(*) = [inf, 0.] + print *, -someInf ! { dg-error "Arithmetic overflow" } + print *, minval(-someInf) ! { dg-error "Arithmetic overflow" } +end -- 2.35.3