Signed-off-by: Jose E. Marchesi <[email protected]>

gcc/algol68/ChangeLog

        * a68-low-units.cc (lower_subscript_for_trimmers): Do not revise
        bounds if no trimscript.

gcc/testsuite/ChangeLog

        * algol68/execute/trimmer-13.a68: New test.
---
 gcc/algol68/a68-low-units.cc                 | 82 ++++++++++++--------
 gcc/testsuite/algol68/execute/trimmer-13.a68 | 13 ++++
 2 files changed, 61 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/algol68/execute/trimmer-13.a68

diff --git a/gcc/algol68/a68-low-units.cc b/gcc/algol68/a68-low-units.cc
index cc1fd15fcca..ba0ab5e2382 100644
--- a/gcc/algol68/a68-low-units.cc
+++ b/gcc/algol68/a68-low-units.cc
@@ -538,11 +538,18 @@ lower_subscript_for_trimmers (NODE_T *p, LOW_CTX_T ctx,
            tree dim_lower_bound = save_expr (a68_multiple_lower_bound 
(multiple, size_dim));
            tree lower_bound = dim_lower_bound;
            tree upper_bound = save_expr (a68_multiple_upper_bound (multiple, 
size_dim));
-           tree at = ssize_int (1);
+           tree at = NULL_TREE;
+
+           bool explicit_lower_bound = false;
+           bool explicit_upper_bound = false;
 
            NODE_T *q = SUB (p);
+
+           /* Process trimscript if present.  */
            if (q != NO_NODE)
              {
+               at = ssize_int (1);
+
                if (IS (q, AT_SYMBOL))
                  {
                    /* Both bounds are implicit.  */
@@ -557,11 +564,11 @@ lower_subscript_for_trimmers (NODE_T *p, LOW_CTX_T ctx,
                        if (IS (q, AT_SYMBOL))
                          {
                            /* Upper bound is implicit, AT specified.  */
-                           gcc_assert (IS (q, AT_SYMBOL));
                            at = save_expr (fold_convert (ssizetype, 
a68_lower_tree (NEXT (q), ctx)));
                          }
                        else
                          {
+                           explicit_upper_bound = true;
                            upper_bound
                              = save_expr (fold_convert (ssizetype, 
a68_lower_tree (q, ctx)));
                            FORWARD (q);
@@ -575,7 +582,7 @@ lower_subscript_for_trimmers (NODE_T *p, LOW_CTX_T ctx,
                  }
                else
                  {
-                   /* Lower bound is explicit.  */
+                   explicit_lower_bound = true;
                    lower_bound = fold_convert (ssizetype, a68_lower_tree (q, 
ctx));
                    FORWARD (q);
                    gcc_assert (IS (q, COLON_SYMBOL));
@@ -586,6 +593,7 @@ lower_subscript_for_trimmers (NODE_T *p, LOW_CTX_T ctx,
                          at = save_expr (fold_convert (ssizetype, 
a68_lower_tree (NEXT (q), ctx)));
                        else
                          {
+                           explicit_upper_bound = true;
                            upper_bound
                              = save_expr (fold_convert (ssizetype, 
a68_lower_tree (q, ctx)));
                            FORWARD (q);
@@ -595,37 +603,40 @@ lower_subscript_for_trimmers (NODE_T *p, LOW_CTX_T ctx,
                          }
                      }
                  }
-             }
 
-           /* Time for some bounds checking.
+               /* Time for some bounds checking.
 
-              Note that in trimmers, given the current dimension's bounds
-              (L,U), we cannot simply do the check:
+                  Note that in trimmers, given the current dimension's bounds
+                  (L,U), we cannot simply do the check:
 
-                   L <= lower_bound <= U
-                   L <= upper_bound <= U
+                    L <= lower_bound <= U
+                    L <= upper_bound <= U
 
-              This is because the multiple may be flat, and the dimension may
-              have bounds such like U < L.  In that case, the expressions
-              above would always eval to false for any lower_bound and
-              upper_bound.
+                  This is because the multiple may be flat, and the dimension
+                  may have bounds such like U < L.  In that case, the
+                  expressions above would always eval to false for any
+                  lower_bound and upper_bound.
 
-              So we check for this instead:
+                  So we check for this instead:
 
-                   L <= lower_bound AND upper_bound <= U
+                    L <= lower_bound AND upper_bound <= U
 
-               This allows to trim a "flat dimension" using a trimmer where
-              upper_bound < lower_bound.  The result is, of course, another
-              "flat dimension" in the multiple result of the trimming.  */
+                    This allows to trim a "flat dimension" using a trimmer
+                    where upper_bound < lower_bound.  The result is, of
+                    course, another "flat dimension" in the multiple result of
+                    the trimming.  */
 
-           if (OPTION_BOUNDS_CHECKING (&A68_JOB))
-             {
-               a68_add_stmt (a68_multiple_single_bound_check (p, size_dim, 
multiple,
-                                                              lower_bound,
-                                                              false /* 
upper_bound */));
-               a68_add_stmt (a68_multiple_single_bound_check (p, size_dim, 
multiple,
-                                                              upper_bound,
-                                                              true /* 
upper_bound */));
+               if (OPTION_BOUNDS_CHECKING (&A68_JOB))
+                 {
+                   if (explicit_lower_bound)
+                     a68_add_stmt (a68_multiple_single_bound_check (p, 
size_dim, multiple,
+                                                                    
lower_bound,
+                                                                    false /* 
upper_bound */));
+                   if (explicit_upper_bound)
+                     a68_add_stmt (a68_multiple_single_bound_check (p, 
size_dim, multiple,
+                                                                    
upper_bound,
+                                                                    true /* 
upper_bound */));
+                 }
              }
 
            /* new_elements += i * strides[dim] */
@@ -650,16 +661,19 @@ lower_subscript_for_trimmers (NODE_T *p, LOW_CTX_T ctx,
            a68_add_stmt (a68_multiple_set_elements_size (new_multiple,
                                                          elements_size));
 
+           /* Correct bounds to the revised lower bound, if necessary.  */
+           if (at != NULL_TREE)
+             {
+               /* Correct bounds to honor the revised lower bound.  */
+               tree d = fold_build2 (MINUS_EXPR, ssizetype, lower_bound, at);
+               lower_bound = fold_build2 (MINUS_EXPR, ssizetype, lower_bound, 
d);
+               upper_bound = fold_build2 (MINUS_EXPR, ssizetype, upper_bound, 
d);
+             }
+
            /* Fill the triplet for this dimension in new_multiple.  */
            tree size_new_dim = size_int (*new_dim);
-           tree d = fold_build2 (MINUS_EXPR, ssizetype, lower_bound, at);
-
-           a68_add_stmt (a68_multiple_set_lower_bound (new_multiple, 
size_new_dim,
-                                                       fold_build2 
(MINUS_EXPR, ssizetype,
-                                                                    
lower_bound, d)));
-           a68_add_stmt (a68_multiple_set_upper_bound (new_multiple, 
size_new_dim,
-                                                       fold_build2 
(MINUS_EXPR, ssizetype,
-                                                                    
upper_bound, d)));
+           a68_add_stmt (a68_multiple_set_lower_bound (new_multiple, 
size_new_dim, lower_bound));
+           a68_add_stmt (a68_multiple_set_upper_bound (new_multiple, 
size_new_dim, upper_bound));
            a68_add_stmt (a68_multiple_set_stride (new_multiple, size_new_dim, 
stride));
 
            *new_dim += 1;
diff --git a/gcc/testsuite/algol68/execute/trimmer-13.a68 
b/gcc/testsuite/algol68/execute/trimmer-13.a68
new file mode 100644
index 00000000000..2ddb1e8ed6e
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/trimmer-13.a68
@@ -0,0 +1,13 @@
+begin [0:9,0:9]int foo;
+      ref[]int bar = foo[2,];
+      assert(UPB foo[2,] = 9);
+      assert(LWB foo[2,] = 0);
+      assert(UPB bar = 9);
+      assert(LWB bar = 0);
+
+      ref[]int baz = foo[2,:];
+      assert(UPB foo[2,:] = 10);
+      assert(LWB foo[2,:] = 1);
+      assert(UPB baz = 10);
+      assert(LWB baz = 1)
+end
-- 
2.39.5

Reply via email to