diff options
author | Harald Anlauf <anlauf@gmx.de> | 2023-01-24 22:36:25 +0100 |
---|---|---|
committer | Harald Anlauf <anlauf@gmx.de> | 2023-01-28 22:00:38 +0100 |
commit | 22afa4947584c701633a79fd8750c9ceeaa96711 (patch) | |
tree | 0ad3fd13f8d8659b748cd4c7f1a1d347111a9444 /gcc/fortran/resolve.cc | |
parent | aba9ff8f30d4245294ea2583de1dc28f1c7ccf7b (diff) | |
download | gcc-22afa4947584c701633a79fd8750c9ceeaa96711.zip gcc-22afa4947584c701633a79fd8750c9ceeaa96711.tar.gz gcc-22afa4947584c701633a79fd8750c9ceeaa96711.tar.bz2 |
Fortran: fix ICE in compare_bound_int [PR108527]
gcc/fortran/ChangeLog:
PR fortran/108527
* resolve.cc (compare_bound_int): Expression to compare must be of
type INTEGER.
(compare_bound_mpz_t): Likewise.
(check_dimension): Fix comment on checks applied to array section
and clean up associated logic.
gcc/testsuite/ChangeLog:
PR fortran/108527
* gfortran.dg/pr108527.f90: New test.
Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
Diffstat (limited to 'gcc/fortran/resolve.cc')
-rw-r--r-- | gcc/fortran/resolve.cc | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 9e2edf7..100b238 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -4575,12 +4575,11 @@ compare_bound_int (gfc_expr *a, int b) { int i; - if (a == NULL || a->expr_type != EXPR_CONSTANT) + if (a == NULL + || a->expr_type != EXPR_CONSTANT + || a->ts.type != BT_INTEGER) return CMP_UNKNOWN; - if (a->ts.type != BT_INTEGER) - gfc_internal_error ("compare_bound_int(): Bad expression"); - i = mpz_cmp_si (a->value.integer, b); if (i < 0) @@ -4598,12 +4597,11 @@ compare_bound_mpz_t (gfc_expr *a, mpz_t b) { int i; - if (a == NULL || a->expr_type != EXPR_CONSTANT) + if (a == NULL + || a->expr_type != EXPR_CONSTANT + || a->ts.type != BT_INTEGER) return CMP_UNKNOWN; - if (a->ts.type != BT_INTEGER) - gfc_internal_error ("compare_bound_int(): Bad expression"); - i = mpz_cmp (a->value.integer, b); if (i < 0) @@ -4733,23 +4731,24 @@ check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as) #define AR_END (ar->end[i] ? ar->end[i] : as->upper[i]) compare_result comp_start_end = compare_bound (AR_START, AR_END); + compare_result comp_stride_zero = compare_bound_int (ar->stride[i], 0); /* Check for zero stride, which is not allowed. */ - if (compare_bound_int (ar->stride[i], 0) == CMP_EQ) + if (comp_stride_zero == CMP_EQ) { gfc_error ("Illegal stride of zero at %L", &ar->c_where[i]); return false; } - /* if start == len || (stride > 0 && start < len) - || (stride < 0 && start > len), + /* if start == end || (stride > 0 && start < end) + || (stride < 0 && start > end), then the array section contains at least one element. In this case, there is an out-of-bounds access if (start < lower || start > upper). */ - if (compare_bound (AR_START, AR_END) == CMP_EQ - || ((compare_bound_int (ar->stride[i], 0) == CMP_GT - || ar->stride[i] == NULL) && comp_start_end == CMP_LT) - || (compare_bound_int (ar->stride[i], 0) == CMP_LT + if (comp_start_end == CMP_EQ + || ((comp_stride_zero == CMP_GT || ar->stride[i] == NULL) + && comp_start_end == CMP_LT) + || (comp_stride_zero == CMP_LT && comp_start_end == CMP_GT)) { if (compare_bound (AR_START, as->lower[i]) == CMP_LT) |