[flang-commits] [flang] 325bd52 - [flang] More subscript triplet checking at compilation time

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Jan 31 08:19:02 PST 2023


Author: Peter Klausler
Date: 2023-01-31T08:18:48-08:00
New Revision: 325bd5289351e0deb71156628c215fe697e44fbc

URL: https://github.com/llvm/llvm-project/commit/325bd5289351e0deb71156628c215fe697e44fbc
DIFF: https://github.com/llvm/llvm-project/commit/325bd5289351e0deb71156628c215fe697e44fbc.diff

LOG: [flang] More subscript triplet checking at compilation time

When a triplet's lower and upper bounds are the same, we can
check them without requiring a constant stride.

Differential Revision: https://reviews.llvm.org/D142943

Added: 
    

Modified: 
    flang/lib/Semantics/expression.cpp
    flang/test/Semantics/expr-errors06.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 966884fb4c32..af6cce3d5b2c 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -319,26 +319,26 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
       auto expr{Fold(triplet->stride())};
       auto stride{ToInt64(expr)};
       triplet->set_stride(std::move(expr));
+      std::optional<ConstantSubscript> lower, upper;
+      if (auto expr{triplet->lower()}) {
+        *expr = Fold(std::move(*expr));
+        lower = ToInt64(*expr);
+        triplet->set_lower(std::move(*expr));
+      } else {
+        lower = ToInt64(lb[dim]);
+      }
+      if (auto expr{triplet->upper()}) {
+        *expr = Fold(std::move(*expr));
+        upper = ToInt64(*expr);
+        triplet->set_upper(std::move(*expr));
+      } else {
+        upper = ToInt64(ub[dim]);
+      }
       if (stride) {
         if (*stride == 0) {
           Say("Stride of triplet must not be zero"_err_en_US);
           return;
         }
-        std::optional<ConstantSubscript> lower, upper;
-        if (auto expr{triplet->lower()}) {
-          *expr = Fold(std::move(*expr));
-          lower = ToInt64(*expr);
-          triplet->set_lower(std::move(*expr));
-        } else {
-          lower = ToInt64(lb[dim]);
-        }
-        if (auto expr{triplet->upper()}) {
-          *expr = Fold(std::move(*expr));
-          upper = ToInt64(*expr);
-          triplet->set_upper(std::move(*expr));
-        } else {
-          upper = ToInt64(ub[dim]);
-        }
         if (lower && upper) {
           if (*stride > 0) {
             anyPossiblyEmptyDim |= *lower > *upper;
@@ -348,8 +348,12 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
         } else {
           anyPossiblyEmptyDim = true;
         }
-      } else {
-        anyPossiblyEmptyDim = true;
+      } else { // non-constant stride
+        if (lower && upper && *lower == *upper) {
+          // stride is not relevant
+        } else {
+          anyPossiblyEmptyDim = true;
+        }
       }
     } else { // not triplet
       auto &expr{std::get<IndirectSubscriptIntegerExpr>(ss.u).value()};
@@ -380,12 +384,13 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
       } else if (ub[dim]) {
         upper = ToInt64(*ub[dim]);
       }
-      if (stride && *stride != 0 && lower && upper) {
-        // Normalize upper bound for non-unit stride
-        // 1:10:2 -> 1:9:2, 10:1:-2 -> 10:2:-2
-        *upper = *lower + *stride * ((*upper - *lower) / *stride);
-        val[vals++] = lower;
-        val[vals++] = upper;
+      if (lower) {
+        val[vals++] = *lower;
+        if (upper && *upper != lower && (stride && *stride != 0)) {
+          // Normalize upper bound for non-unit stride
+          // 1:10:2 -> 1:9:2, 10:1:-2 -> 10:2:-2
+          val[vals++] = *lower + *stride * ((*upper - *lower) / *stride);
+        }
       }
     } else {
       val[vals++] =

diff  --git a/flang/test/Semantics/expr-errors06.f90 b/flang/test/Semantics/expr-errors06.f90
index ad5baf708f34..1168d410b9bd 100644
--- a/flang/test/Semantics/expr-errors06.f90
+++ b/flang/test/Semantics/expr-errors06.f90
@@ -2,6 +2,7 @@
 ! Check out-of-range subscripts
 real a(10)
 integer, parameter :: n(2) = [1, 2]
+integer unknown
 !ERROR: DATA statement designator 'a(0_8)' is out of range
 !ERROR: DATA statement designator 'a(11_8)' is out of range
 data a(0)/0./, a(10+1)/0./
@@ -25,5 +26,8 @@
 print *, a(10:-2:-3)
 print *, a(-1:-2) ! empty section is ok
 print *, a(0:11:-1) ! empty section is ok
+!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
+print *, a(0:0:unknown) ! lower==upper, can ignore stride
+!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
+print *, a(11:11:unknown) ! lower==upper, can ignore stride
 end
-


        


More information about the flang-commits mailing list