[flang-commits] [flang] 5242018 - [flang] Catch attempts to subscribe empty arrays (#108246)

via flang-commits flang-commits at lists.llvm.org
Thu Sep 12 09:11:57 PDT 2024


Author: Peter Klausler
Date: 2024-09-12T09:11:54-07:00
New Revision: 524201881562d696841561e44f0a70a7cc7dc18d

URL: https://github.com/llvm/llvm-project/commit/524201881562d696841561e44f0a70a7cc7dc18d
DIFF: https://github.com/llvm/llvm-project/commit/524201881562d696841561e44f0a70a7cc7dc18d.diff

LOG: [flang] Catch attempts to subscribe empty arrays (#108246)

An array that has one or more empty dimensions cannot have subscripts
unless there's a possibility that they constitute an empty array
section.

We previously only checked that constant subscripts are in bounds.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h
index b1304d704232dc..c90c8c4b3cc70f 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -331,7 +331,7 @@ class ExpressionAnalyzer {
       const semantics::Scope &, bool C919bAlreadyEnforced = false);
   MaybeExpr CompleteSubscripts(ArrayRef &&);
   MaybeExpr ApplySubscripts(DataRef &&, std::vector<Subscript> &&);
-  void CheckConstantSubscripts(ArrayRef &);
+  void CheckSubscripts(ArrayRef &);
   bool CheckRanks(const DataRef &); // Return false if error exists.
   bool CheckPolymorphic(const DataRef &); // ditto
   bool CheckDataRef(const DataRef &); // ditto

diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index e94a49f6871db4..072ebe172f45a9 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -298,7 +298,7 @@ MaybeExpr ExpressionAnalyzer::CompleteSubscripts(ArrayRef &&ref) {
     // Subscripts of named constants are checked in folding.
     // Subscripts of DATA statement objects are checked in data statement
     // conversion to initializers.
-    CheckConstantSubscripts(ref);
+    CheckSubscripts(ref);
   }
   return Designate(DataRef{std::move(ref)});
 }
@@ -326,7 +326,7 @@ MaybeExpr ExpressionAnalyzer::ApplySubscripts(
       std::move(dataRef.u));
 }
 
-void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
+void ExpressionAnalyzer::CheckSubscripts(ArrayRef &ref) {
   // Fold subscript expressions and check for an empty triplet.
   const Symbol &arraySymbol{ref.base().GetLastSymbol()};
   Shape lb{GetLBOUNDs(foldingContext_, NamedEntity{arraySymbol})};
@@ -390,6 +390,13 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
   for (Subscript &ss : ref.subscript()) {
     auto dimLB{ToInt64(lb[dim])};
     auto dimUB{ToInt64(ub[dim])};
+    if (dimUB && dimLB && *dimUB < *dimLB) {
+      AttachDeclaration(
+          Say("Empty array dimension %d cannot be subscripted as an element or non-empty array section"_err_en_US,
+              dim + 1),
+          arraySymbol);
+      break;
+    }
     std::optional<ConstantSubscript> val[2];
     int vals{0};
     if (auto *triplet{std::get_if<Triplet>(&ss.u)}) {

diff  --git a/flang/test/Semantics/expr-errors06.f90 b/flang/test/Semantics/expr-errors06.f90
index 84872c7fcdbc58..bdcb92cbe5e4df 100644
--- a/flang/test/Semantics/expr-errors06.f90
+++ b/flang/test/Semantics/expr-errors06.f90
@@ -1,7 +1,7 @@
 ! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
 ! Check out-of-range subscripts
 subroutine subr(da)
-  real a(10), da(2,1)
+  real a(10), da(2,1), empty(1:0,1)
   integer, parameter :: n(2) = [1, 2]
   integer unknown
   !ERROR: DATA statement designator 'a(0_8)' is out of range
@@ -39,4 +39,10 @@ subroutine subr(da)
   print *, da(1,0)
   !WARNING: Subscript 2 is greater than upper bound 1 for dimension 2 of array
   print *, da(1,2)
+  print *, empty([(j,j=1,0)],1) ! ok
+  print *, empty(1:0,1) ! ok
+  print *, empty(:,1) ! ok
+  print *, empty(i:j,k) ! ok
+  !ERROR: Empty array dimension 1 cannot be subscripted as an element or non-empty array section
+  print *, empty(i,1)
 end


        


More information about the flang-commits mailing list