Hi Fritz,
First, it appears if simplify_bound_dim returns &gfc_bad_expr (and a div/0 occurs) then this code will free &gfc_bad_expr. I'm not sure whether or not that can actually occur, but it is certainly incorrect, since &gfc_bad_expr points to static storage. The only other possible case is bounds[d] == NULL, in which case the free is a no-op. I suggest removing the free call.
OK, removed.
That being said, it looks like the same error condition can occur with the lcobound intrinsic.
I have adjusted the test case so it also checks for the coarray case; this is handled correctly with a "Divion by zero" error without changing the patch in that respect. So, anything else? If not, I will commit this within a few days. Regards Thomas
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 9b95200c241..650837e18c3 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -3986,6 +3986,9 @@ resolve_operator (gfc_expr *e) op1 = e->value.op.op1; op2 = e->value.op.op2; + if (op1 == NULL && op2 == NULL) + return false; + dual_locus_error = false; /* op1 and op2 cannot both be BOZ. */ diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 807565b4e80..855fbe27d9f 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4251,7 +4251,11 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper) for (j = 0; j < d; j++) gfc_free_expr (bounds[j]); - return bounds[d]; + + if (gfc_seen_div0) + return &gfc_bad_expr; + else + return bounds[d]; } } diff --git a/gcc/testsuite/gfortran.dg/arith_divide_3.f90 b/gcc/testsuite/gfortran.dg/arith_divide_3.f90 new file mode 100644 index 00000000000..95682dfdda7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/arith_divide_3.f90 @@ -0,0 +1,17 @@ +! { dg-do compile } +! { dg-options "-fcoarray=single" } +! PR 93500 - this used to cause an ICE + +program p + integer :: a(min(2,0)/0) ! { dg-error "Division by zero" } + integer, save :: c[min(2,0)/0,*] ! { dg-error "Division by zero|must have constant shape" } + integer :: b = lbound(a) ! { dg-error "must be an array" } + print *,lcobound(c) +end program p + +subroutine s + integer :: a(min(2,0)/0) ! { dg-error "Division by zero" } + integer, save :: c[min(2,0)/0,*] ! { dg-error "Division by zero" } + integer :: b = lbound(a) + print *,lcobound(c) +end subroutine s