diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2019-12-30 10:34:11 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2019-12-30 10:34:11 +0000 |
commit | 672511187345d30ccd725214ac4b34b181bd6569 (patch) | |
tree | 4dd5ef16a039f4e241f8d2222b19e3661cd794a5 /gcc/fortran/decl.c | |
parent | c3182576ea48f175283e291094298831dd7046e5 (diff) | |
download | gcc-672511187345d30ccd725214ac4b34b181bd6569.zip gcc-672511187345d30ccd725214ac4b34b181bd6569.tar.gz gcc-672511187345d30ccd725214ac4b34b181bd6569.tar.bz2 |
Catch division by zero errors in array sizes.
2019-12-30 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, set gfc_seen_div0.
* decl.c (variable_decl): If resolution resp. simplification
fails for array spec and a division of zero error has been
seen, return MATCH_ERROR.
2019-12-30 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/92961
* gfortran.dg/arith_divide_2.f90: New test.
From-SVN: r279762
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r-- | gcc/fortran/decl.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index affdbf6..b43dc2c 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -2535,6 +2535,8 @@ variable_decl (int elem) goto cleanup; } + 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. */ @@ -2551,7 +2553,12 @@ variable_decl (int elem) for (int i = 0; i < as->rank; i++) { e = gfc_copy_expr (as->lower[i]); - gfc_resolve_expr (e); + if (!gfc_resolve_expr (e) && gfc_seen_div0) + { + m = MATCH_ERROR; + goto cleanup; + } + gfc_simplify_expr (e, 0); if (e && (e->expr_type != EXPR_CONSTANT)) { @@ -2561,7 +2568,12 @@ variable_decl (int elem) gfc_free_expr (e); e = gfc_copy_expr (as->upper[i]); - gfc_resolve_expr (e); + if (!gfc_resolve_expr (e) && gfc_seen_div0) + { + m = MATCH_ERROR; + goto cleanup; + } + gfc_simplify_expr (e, 0); if (e && (e->expr_type != EXPR_CONSTANT)) { @@ -2587,7 +2599,12 @@ variable_decl (int elem) if (e->expr_type != EXPR_CONSTANT) { n = gfc_copy_expr (e); - gfc_simplify_expr (n, 1); + if (!gfc_simplify_expr (n, 1) && gfc_seen_div0) + { + m = MATCH_ERROR; + goto cleanup; + } + if (n->expr_type == EXPR_CONSTANT) gfc_replace_expr (e, n); else @@ -2597,7 +2614,12 @@ variable_decl (int elem) if (e->expr_type != EXPR_CONSTANT) { n = gfc_copy_expr (e); - gfc_simplify_expr (n, 1); + if (!gfc_simplify_expr (n, 1) && gfc_seen_div0) + { + m = MATCH_ERROR; + goto cleanup; + } + if (n->expr_type == EXPR_CONSTANT) gfc_replace_expr (e, n); else @@ -2934,6 +2956,7 @@ variable_decl (int elem) cleanup: /* Free stuff up and return. */ + gfc_seen_div0 = false; gfc_free_expr (initializer); gfc_free_array_spec (as); |