stmtblock_t body;
stmtblock_t ifbody;
gfc_loopinfo loop;
- tree orig_nelems = nelems; /* Needed for bounds check. */
gfc_init_block (&body);
tmp = fold_build2_loc (input_location, MINUS_EXPR,
/* Add bounds check. */
if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
{
- char *msg;
const char *name = "<<unknown>>";
- tree from_len;
+ int dim, rank;
if (DECL_P (to))
- name = (const char *)(DECL_NAME (to)->identifier.id.str);
-
- from_len = gfc_conv_descriptor_size (from_data, 1);
- from_len = fold_convert (TREE_TYPE (orig_nelems), from_len);
- tmp = fold_build2_loc (input_location, NE_EXPR,
- logical_type_node, from_len, orig_nelems);
- msg = xasprintf ("Array bound mismatch for dimension %d "
- "of array '%s' (%%ld/%%ld)",
- 1, name);
-
- gfc_trans_runtime_check (true, false, tmp, &body,
- &gfc_current_locus, msg,
- fold_convert (long_integer_type_node, orig_nelems),
- fold_convert (long_integer_type_node, from_len));
+ name = IDENTIFIER_POINTER (DECL_NAME (to));
- free (msg);
+ rank = GFC_TYPE_ARRAY_RANK (TREE_TYPE (from_data));
+ for (dim = 1; dim <= rank; dim++)
+ {
+ tree from_len, to_len, cond;
+ char *msg;
+
+ from_len = gfc_conv_descriptor_size (from_data, dim);
+ from_len = fold_convert (long_integer_type_node, from_len);
+ to_len = gfc_conv_descriptor_size (to_data, dim);
+ to_len = fold_convert (long_integer_type_node, to_len);
+ msg = xasprintf ("Array bound mismatch for dimension %d "
+ "of array '%s' (%%ld/%%ld)",
+ dim, name);
+ cond = fold_build2_loc (input_location, NE_EXPR,
+ logical_type_node, from_len, to_len);
+ gfc_trans_runtime_check (true, false, cond, &body,
+ &gfc_current_locus, msg,
+ to_len, from_len);
+ free (msg);
+ }
}
tmp = build_call_vec (fcn_type, fcn, args);
--- /dev/null
+! { dg-do run }
+! { dg-additional-options "-fcheck=bounds -fdump-tree-original" }
+!
+! PR fortran/86100 - bogus bounds check with assignment, class component
+
+program p
+ implicit none
+ type any_matrix
+ class(*), allocatable :: m(:,:)
+ end type any_matrix
+ type(any_matrix) :: a, b
+ allocate (a%m, source=reshape([3,5],shape=[1,2]))
+
+ ! The following assignment did create a bogus bounds violation:
+ b = a ! Line 15
+ if (any (shape (b%m) /= shape (a%m))) stop 1
+
+contains
+
+ ! Verify improved array name in array name
+ subroutine bla ()
+ type(any_matrix) :: c, d
+ allocate (real :: c%m(3,5))
+ allocate (d%m(7,9),source=c%m) ! Line 24
+ end subroutine bla
+end
+
+! { dg-final { scan-tree-dump-times "line 15 .* bound mismatch for dimension 1 of array .'.*.'" 1 "original" } }
+! { dg-final { scan-tree-dump-times "line 15 .* bound mismatch for dimension 2 of array .'.*.'" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "line 24 .* bound mismatch for dimension 1 of array .'d%%m.'" 1 "original" } }
+! { dg-final { scan-tree-dump-times "line 24 .* bound mismatch for dimension 2 of array .'d%%m.'" 1 "original" } }