diff mbox series

[pach,fortran] Fix PR 92961, ICE on division by zero error in array bounds

Message ID 8b0eb556-853e-09d5-2e16-b20b856759f1@netcologne.de
State New
Headers show
Series [pach,fortran] Fix PR 92961, ICE on division by zero error in array bounds | expand

Commit Message

Thomas Koenig Dec. 20, 2019, 2:24 p.m. UTC
Hello world,

the attached patch fixes an ICE in an array declaration where the
specified size came from 0/0. This is an 8/9/10 regression.

The actual ICE fix was the NULL check in simplify_intrinsic_op, which in
turn led to strange error messages, which are then corrected by
the rest of the patch. Rather than try to transport state across I
do not know how many levels of calls, I chose a global variable.

Regression-tested. OK for all affected branches?

Regards

	Thomas

2019-12-20  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/92961
	* gfortran.h (gfc_seen_div0): Add declaration.
	* arith.h (gfc_seen_div0): Add definition.
	(eval_intrinsic): For integer division by zero, issue
	gfc_error_now and set gfc_seen_div0.
	* decl.c (variable_decl): If a division by zero error has been
	seen previously, do not issue an addtional error.
	* expr.c (simplify_intrinsic_op): Return NULL if op1 is NULL.

2019-12-20  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/92961
	* gfortran.dg/arith_divide_2.f90: New test.

Comments

Thomas Koenig Dec. 20, 2019, 3:09 p.m. UTC | #1
> the attached patch fixes an ICE in an array declaration where the
> specified size came from 0/0. This is an 8/9/10 regression.

Actually, it does not fix all testcases in the PR, so some more
tweaking is still needed.

Regards

	Thomas
diff mbox series

Patch

Index: gfortran.h
===================================================================
--- gfortran.h	(Revision 279639)
+++ gfortran.h	(Arbeitskopie)
@@ -2995,6 +2995,8 @@  void gfc_arith_done_1 (void);
 arith gfc_check_integer_range (mpz_t p, int kind);
 bool gfc_check_character_range (gfc_char_t, int);
 
+extern bool gfc_seen_div0;
+
 /* trans-types.c */
 bool gfc_check_any_c_kind (gfc_typespec *);
 int gfc_validate_kind (bt, int, bool);
Index: arith.c
===================================================================
--- arith.c	(Revision 279639)
+++ arith.c	(Arbeitskopie)
@@ -32,6 +32,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "target-memory.h"
 #include "constructor.h"
 
+bool gfc_seen_div0;
+
 /* MPFR does not have a direct replacement for mpz_set_f() from GMP.
    It's easily implemented with a few calls though.  */
 
@@ -1617,7 +1619,15 @@  eval_intrinsic (gfc_intrinsic_op op,
 
   if (rc != ARITH_OK)
     {
-      gfc_error (gfc_arith_error (rc), &op1->where);
+      if (rc == ARITH_DIV0 && op2->ts.type == BT_INTEGER)
+	{
+	  gfc_error_now (gfc_arith_error (rc), &op2->where);
+	  gfc_seen_div0 = true;
+	  return NULL;
+	}
+      else
+	gfc_error (gfc_arith_error (rc), &op1->where);
+
       if (rc == ARITH_OVERFLOW)
 	goto done;
       return NULL;
Index: decl.c
===================================================================
--- decl.c	(Revision 279639)
+++ decl.c	(Arbeitskopie)
@@ -2535,6 +2535,10 @@  variable_decl (int elem)
 	  goto cleanup;
 	}
 
+      /* eval_intrinsic may signal a division by zero.  */
+
+      gfc_seen_div0 = false;
+
       /* F2018:C830 (R816) An explicit-shape-spec whose bounds are not
 	 constant expressions shall appear only in a subprogram, derived
 	 type definition, BLOCK construct, or interface body.  */
@@ -2573,7 +2577,15 @@  variable_decl (int elem)
 
 	  if (not_constant)
 	    {
-	      gfc_error ("Explicit shaped array with nonconstant bounds at %C");
+	      /* If there is a division by zero error, it will have been reported
+		 previously using gfc_error_now in eval_intrinsic.  */
+
+	      if (!gfc_seen_div0)
+		gfc_error ("Explicit shaped array with nonconstant bounds at "
+			   "%C");
+
+	      gfc_seen_div0 = false;
+
 	      m = MATCH_ERROR;
 	      goto cleanup;
 	    }
Index: expr.c
===================================================================
--- expr.c	(Revision 279639)
+++ expr.c	(Arbeitskopie)
@@ -1153,6 +1153,9 @@  simplify_intrinsic_op (gfc_expr *p, int type)
   op2 = p->value.op.op2;
   op  = p->value.op.op;
 
+  if (op1 == NULL)
+    return false;
+
   if (!gfc_simplify_expr (op1, type))
     return false;
   if (!gfc_simplify_expr (op2, type))