Skip to content

Conversation

@klausler
Copy link
Contributor

@klausler klausler commented Jan 9, 2025

Fixes #122002.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:semantics labels Jan 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 9, 2025

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

Changes

Fixes #122002.


Full diff: https://github.com/llvm/llvm-project/pull/122364.diff

2 Files Affected:

  • (modified) flang/lib/Evaluate/shape.cpp (+13-7)
  • (added) flang/test/Semantics/bug122002.f90 (+5)
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index c7b2156a3de17a..a078d753ba5ee0 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -254,7 +254,8 @@ class GetLowerBoundHelper
       if (dimension_ < rank) {
         const semantics::ShapeSpec &shapeSpec{object->shape()[dimension_]};
         if (shapeSpec.lbound().isExplicit()) {
-          if (const auto &lbound{shapeSpec.lbound().GetExplicit()}) {
+          if (const auto &lbound{shapeSpec.lbound().GetExplicit()};
+              lbound && lbound->Rank() == 0) {
             if constexpr (LBOUND_SEMANTICS) {
               bool ok{false};
               auto lbValue{ToInt64(*lbound)};
@@ -266,7 +267,8 @@ class GetLowerBoundHelper
               } else if (lbValue.value_or(0) == 1) {
                 // Lower bound is 1, regardless of extent
                 ok = true;
-              } else if (const auto &ubound{shapeSpec.ubound().GetExplicit()}) {
+              } else if (const auto &ubound{shapeSpec.ubound().GetExplicit()};
+                  ubound && ubound->Rank() == 0) {
                 // If we can't prove that the dimension is nonempty,
                 // we must be conservative.
                 // TODO: simple symbolic math in expression rewriting to
@@ -459,7 +461,7 @@ static MaybeExtentExpr GetNonNegativeExtent(
     } else {
       return ExtentExpr{*uval - *lval + 1};
     }
-  } else if (lbound && ubound &&
+  } else if (lbound && ubound && lbound->Rank() == 0 && ubound->Rank() == 0 &&
       (!invariantOnly ||
           (IsScopeInvariantExpr(*lbound) && IsScopeInvariantExpr(*ubound)))) {
     // Apply effective IDIM (MAX calculation with 0) so thet the
@@ -608,7 +610,8 @@ MaybeExtentExpr GetRawUpperBound(
     int rank{details->shape().Rank()};
     if (dimension < rank) {
       const auto &bound{details->shape()[dimension].ubound().GetExplicit()};
-      if (bound && (!invariantOnly || IsScopeInvariantExpr(*bound))) {
+      if (bound && bound->Rank() == 0 &&
+          (!invariantOnly || IsScopeInvariantExpr(*bound))) {
         return *bound;
       } else if (semantics::IsAssumedSizeArray(symbol) &&
           dimension + 1 == symbol.Rank()) {
@@ -640,7 +643,8 @@ MaybeExtentExpr GetRawUpperBound(FoldingContext &context,
 static MaybeExtentExpr GetExplicitUBOUND(FoldingContext *context,
     const semantics::ShapeSpec &shapeSpec, bool invariantOnly) {
   const auto &ubound{shapeSpec.ubound().GetExplicit()};
-  if (ubound && (!invariantOnly || IsScopeInvariantExpr(*ubound))) {
+  if (ubound && ubound->Rank() == 0 &&
+      (!invariantOnly || IsScopeInvariantExpr(*ubound))) {
     if (auto extent{GetNonNegativeExtent(shapeSpec, invariantOnly)}) {
       if (auto cstExtent{ToInt64(
               context ? Fold(*context, std::move(*extent)) : *extent)}) {
@@ -731,7 +735,8 @@ MaybeExtentExpr GetLCOBOUND(
     if (dimension < corank) {
       const semantics::ShapeSpec &shapeSpec{object->coshape()[dimension]};
       if (const auto &lcobound{shapeSpec.lbound().GetExplicit()}) {
-        if (!invariantOnly || IsScopeInvariantExpr(*lcobound)) {
+        if (lcobound->Rank() == 0 &&
+            (!invariantOnly || IsScopeInvariantExpr(*lcobound))) {
           return *lcobound;
         }
       }
@@ -748,7 +753,8 @@ MaybeExtentExpr GetUCOBOUND(
     if (dimension < corank - 1) {
       const semantics::ShapeSpec &shapeSpec{object->coshape()[dimension]};
       if (const auto ucobound{shapeSpec.ubound().GetExplicit()}) {
-        if (!invariantOnly || IsScopeInvariantExpr(*ucobound)) {
+        if (ucobound->Rank() == 0 &&
+            (!invariantOnly || IsScopeInvariantExpr(*ucobound))) {
           return *ucobound;
         }
       }
diff --git a/flang/test/Semantics/bug122002.f90 b/flang/test/Semantics/bug122002.f90
new file mode 100644
index 00000000000000..18fbed92a05f50
--- /dev/null
+++ b/flang/test/Semantics/bug122002.f90
@@ -0,0 +1,5 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! ERROR: Missing initialization for parameter 'n'
+! ERROR: Must be a scalar value, but is a rank-1 array
+integer, parameter :: n(n)
+end

Fixes llvm#122002.
The compiler now survives both of the test cases in that bug report.
@klausler klausler merged commit b720b6c into llvm:main Jan 14, 2025
8 checks passed
@klausler klausler deleted the bug122002 branch January 14, 2025 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:semantics flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[flang] stack-overflow in Fortran::evaluate::GetShapeHelper::CreateShape

3 participants