Hi, the attached should be mostly self-explaining. Division by zero handling appeared to be incomplete. It was not dealt with properly when occurring in declaration statements. We now try to handle this.
OK for mainline? Thanks, Harald PR fortran/93499 - ICE on division by zero in declaration statements Division by zero in declaration statements could sometimes generate NULL pointers being passed around that lead to ICEs. gcc/fortran/ChangeLog: 2020-05-09 Harald Anlauf <anl...@gmx.de> PR fortran/93499 * arith.c (gfc_divide): Catch division by zero. (eval_intrinsic_f3): Safeguard for NULL operands. gcc/testsuite/ChangeLog: 2020-05-09 Harald Anlauf <anl...@gmx.de> PR fortran/93499 * gfortran.dg/pr93499.f90: New test.
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c index 422ef40c431..1cd0867a941 100644 --- a/gcc/fortran/arith.c +++ b/gcc/fortran/arith.c @@ -1746,6 +1746,9 @@ eval_intrinsic_f3 (gfc_intrinsic_op op, gfc_expr *result; eval_f f; + if (!op1 && !op2) + return NULL; + result = reduce_binary0 (op1, op2); if (result != NULL) return eval_type_intrinsic0(op, result); @@ -1803,6 +1806,37 @@ gfc_multiply (gfc_expr *op1, gfc_expr *op2) gfc_expr * gfc_divide (gfc_expr *op1, gfc_expr *op2) { + if (op2 && op2->expr_type == EXPR_CONSTANT) + { + arith rc = ARITH_OK; + switch (op2->ts.type) + { + case BT_INTEGER: + /* non-integer divided by integer 0 is handled elsewhere. */ + if (mpz_sgn (op2->value.integer) == 0 + && op1->ts.type == BT_INTEGER) + rc = ARITH_DIV0; + break; + case BT_REAL: + if (mpfr_sgn (op2->value.real) == 0 + && flag_range_check == 1) + rc = ARITH_DIV0; + break; + case BT_COMPLEX: + if (mpc_cmp_si_si (op2->value.complex, 0, 0) == 0 + && flag_range_check == 1) + rc = ARITH_DIV0; + break; + default: + gfc_internal_error ("gfc_divide(): Bad basic type"); + } + if (rc == ARITH_DIV0) + { + gfc_seen_div0 = true; + gfc_error ("Division by zero at %L", &op2->where); + return NULL; + } + } return eval_intrinsic_f3 (INTRINSIC_DIVIDE, gfc_arith_divide, op1, op2); } diff --git a/gcc/testsuite/gfortran.dg/pr93499.f90 b/gcc/testsuite/gfortran.dg/pr93499.f90 new file mode 100644 index 00000000000..7a414bb6016 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr93499.f90 @@ -0,0 +1,10 @@ +! { dg-do compile } +! PR 93499 - this used to ICE. Original test case by Gerhard Steinmetz. + +program p + integer :: a((0.)/0) ! { dg-error "Division by zero" } + type t(n) + integer, len :: n + end type t + type(t((0)/0)) :: x ! { dg-error "Division by zero" } +end