aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Anlauf <anlauf@gmx.de>2023-08-31 22:19:58 +0200
committerHarald Anlauf <anlauf@gmx.de>2023-09-01 22:25:20 +0200
commit6f06152541d62ae7c8579b7d7bf552be19e15b05 (patch)
treed2807d4c8e124754ad854ec32d784d26cf97429c
parente7b267444045c507654a2a3f758efee5d5b550df (diff)
downloadgcc-6f06152541d62ae7c8579b7d7bf552be19e15b05.zip
gcc-6f06152541d62ae7c8579b7d7bf552be19e15b05.tar.gz
gcc-6f06152541d62ae7c8579b7d7bf552be19e15b05.tar.bz2
Fortran: runtime bounds-checking in presence of array constructors [PR31059]
gcc/fortran/ChangeLog: PR fortran/31059 * trans-array.cc (gfc_conv_ss_startstride): For array bounds checking, consider also array constructors in expressions, and use their shape. gcc/testsuite/ChangeLog: PR fortran/31059 * gfortran.dg/bounds_check_fail_5.f90: New test.
-rw-r--r--gcc/fortran/trans-array.cc23
-rw-r--r--gcc/testsuite/gfortran.dg/bounds_check_fail_5.f9026
2 files changed, 49 insertions, 0 deletions
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 90a7d4e..6ca58e9 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -4740,6 +4740,29 @@ done:
for (n = 0; n < loop->dimen; n++)
size[n] = NULL_TREE;
+ /* If there is a constructor involved, derive size[] from its shape. */
+ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ gfc_ss_info *ss_info;
+
+ ss_info = ss->info;
+ info = &ss_info->data.array;
+
+ if (ss_info->type == GFC_SS_CONSTRUCTOR && info->shape)
+ {
+ for (n = 0; n < loop->dimen; n++)
+ {
+ if (size[n] == NULL)
+ {
+ gcc_assert (info->shape[n]);
+ size[n] = gfc_conv_mpz_to_tree (info->shape[n],
+ gfc_index_integer_kind);
+ }
+ }
+ break;
+ }
+ }
+
for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
{
stmtblock_t inner;
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_fail_5.f90 b/gcc/testsuite/gfortran.dg/bounds_check_fail_5.f90
new file mode 100644
index 0000000..436cc96
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/bounds_check_fail_5.f90
@@ -0,0 +1,26 @@
+! { dg-do run }
+! { dg-additional-options "-fcheck=bounds -g -fdump-tree-original" }
+! { dg-output "At line 13 .*" }
+! { dg-shouldfail "Array bound mismatch for dimension 1 of array 'ivec' (2/3)" }
+!
+! PR fortran/31059 - runtime bounds-checking in presence of array constructors
+
+program p
+ integer :: jvec(3) = [1,2,3]
+ integer, allocatable :: ivec(:), kvec(:), lvec(:), mvec(:), nvec(:)
+ ivec = [1,2] ! (re)allocation
+ kvec = [4,5,6] ! (re)allocation
+ ivec(:) = [4,5,6] ! runtime error (->dump)
+ ! not reached ...
+ print *, jvec + [1,2,3] ! OK & no check generated
+ print *, [4,5,6] + jvec ! OK & no check generated
+ print *, lvec + [1,2,3] ! check generated (->dump)
+ print *, [4,5,6] + mvec ! check generated (->dump)
+ nvec(:) = jvec ! check generated (->dump)
+end
+
+! { dg-final { scan-tree-dump-times "Array bound mismatch " 4 "original" } }
+! { dg-final { scan-tree-dump-times "Array bound mismatch .*ivec" 1 "original" } }
+! { dg-final { scan-tree-dump-times "Array bound mismatch .*lvec" 1 "original" } }
+! { dg-final { scan-tree-dump-times "Array bound mismatch .*mvec" 1 "original" } }
+! { dg-final { scan-tree-dump-times "Array bound mismatch .*nvec" 1 "original" } }