diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e69ff8e4f42..7acc4c6c2fd 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2018-06-07 Steven G. Kargl + + PR fortran/86045 + * simplify.c (gfc_simplify_mod): Re-arrange code to test whether + 'P' is zero and issue an error if it is. + 2018-06-06 Thomas Koenig PR fortran/85641 diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index fdd85edf62c..41997367cf9 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -5473,41 +5473,46 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p) gfc_expr *result; int kind; - if (a->expr_type != EXPR_CONSTANT || p->expr_type != EXPR_CONSTANT) + /* First check p. */ + if (p->expr_type != EXPR_CONSTANT) + return NULL; + + /* p shall not be 0. */ + switch (p->ts.type) + { + case BT_INTEGER: + if (mpz_cmp_ui (p->value.integer, 0) == 0) + { + gfc_error ("Argument %qs of MOD at %L shall not be zero", + "P", &p->where); + return &gfc_bad_expr; + } + break; + case BT_REAL: + if (mpfr_cmp_ui (p->value.real, 0) == 0) + { + gfc_error ("Argument %qs of MOD at %L shall not be zero", + "P", &p->where); + return &gfc_bad_expr; + } + break; + default: + gfc_internal_error ("gfc_simplify_mod(): Bad arguments"); + } + + if (a->expr_type != EXPR_CONSTANT) return NULL; kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind; result = gfc_get_constant_expr (a->ts.type, kind, &a->where); - switch (a->ts.type) + if (a->ts.type == BT_INTEGER) + mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer); + else { - case BT_INTEGER: - if (mpz_cmp_ui (p->value.integer, 0) == 0) - { - /* Result is processor-dependent. */ - gfc_error ("Second argument MOD at %L is zero", &a->where); - gfc_free_expr (result); - return &gfc_bad_expr; - } - mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer); - break; - - case BT_REAL: - if (mpfr_cmp_ui (p->value.real, 0) == 0) - { - /* Result is processor-dependent. */ - gfc_error ("Second argument of MOD at %L is zero", &p->where); - gfc_free_expr (result); - return &gfc_bad_expr; - } - - gfc_set_model_kind (kind); - mpfr_fmod (result->value.real, a->value.real, p->value.real, - GFC_RND_MODE); - break; - - default: - gfc_internal_error ("gfc_simplify_mod(): Bad arguments"); + gfc_set_model_kind (kind); + mpfr_fmod (result->value.real, a->value.real, p->value.real, + GFC_RND_MODE); } return range_check (result, "MOD"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 691d233e3b7..f26dd5b2f58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-06-07 Steven G. Kargl + + PR fortran/86045 + * gfortran.dg/pr86045.f90: New test. + 2018-06-07 Marek Polacek * g++.dg/cpp0x/range-for9.C: Adjust dg-error. diff --git a/gcc/testsuite/gfortran.dg/pr86045.f90 b/gcc/testsuite/gfortran.dg/pr86045.f90 new file mode 100644 index 00000000000..685672f1dbd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr86045.f90 @@ -0,0 +1,7 @@ +! { dg-do compile } +program p + logical :: a(2) = (mod([2,3],0) == 0) ! { dg-error "shall not be zero" } + integer :: b = count(mod([2,3],0) == 0) ! { dg-error "shall not be zero" } + integer :: c = all(mod([2,3],0) == 0) ! { dg-error "shall not be zero" } + integer :: d = any(mod([2,3],0) == 0) ! { dg-error "shall not be zero" } +end