On Fri, Mar 09, 2018 at 09:13:10PM -0800, Steve Kargl wrote: > In fixing PR fortran/83633, it seems the patch I committed > introduced an ICE for nonsensical invalid Fortran. The > attached patch cures the ICE and now (re)issues an error > message. > > The basic problem seems to boil down to the recursive > calling of gfc_simplify_expr reduces "huge(1_8)+1_8" to > "constant + constant". When the chain of gfc_simplify_expr > tries to reduces this expression an overflow occurs. An > error message is queud but never emitted, and the result > is set to NULL and both constants are freed. The NULL is > passed back up through the chain of gfc_simplify_expr. > At some point that NULL pointer is referenced. The patch > works around the problem by passing the result with the > overflow value up the chain. > > Regression tested on x86_64-*-freebsd. I intend to commit > this patch tomorrow, which on my clock is only 2.75 hours > away. > > 2018-03-09 Steven G. Kargl <ka...@gcc.gnu.org> > > PR fortran/84734 > * arith.c (check_result, eval_intrinsic): If result overflows, pass > the expression up the chain instead of a NULL pointer. > > 2018-03-09 Steven G. Kargl <ka...@gcc.gnu.org> > > PR fortran/84734 > * gfortran.dg/pr84734.f90: New test. >
Now with an attached patch. -- Steve
Index: gcc/fortran/arith.c =================================================================== --- gcc/fortran/arith.c (revision 258367) +++ gcc/fortran/arith.c (working copy) @@ -555,10 +555,10 @@ check_result (arith rc, gfc_expr *x, gfc_expr *r, gfc_ val = ARITH_OK; } - if (val != ARITH_OK) - gfc_free_expr (r); - else + if (val == ARITH_OK || val == ARITH_OVERFLOW) *rp = r; + else + gfc_free_expr (r); return val; } @@ -1603,8 +1603,12 @@ eval_intrinsic (gfc_intrinsic_op op, if (rc != ARITH_OK) { gfc_error (gfc_arith_error (rc), &op1->where); + if (rc == ARITH_OVERFLOW) + goto done; return NULL; } + +done: gfc_free_expr (op1); gfc_free_expr (op2); Index: gcc/testsuite/gfortran.dg/pr84734.f90 =================================================================== --- gcc/testsuite/gfortran.dg/pr84734.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/pr84734.f90 (working copy) @@ -0,0 +1,4 @@ +! { dg-do compile } +! PR fortran/84734 + integer :: b(huge(1_8)+1_8) = 0 ! { dg-error "Arithmetic overflow" } + end