Index: flang/lib/Evaluate/fold-integer.cpp =================================================================== --- flang/lib/Evaluate/fold-integer.cpp +++ flang/lib/Evaluate/fold-integer.cpp @@ -29,6 +29,37 @@ } } +class GetConstantArrayShapeHelper { +public: + GetConstantArrayShapeHelper(std::optional dim) + : dim_{dim} {} + + template ConstantSubscripts Get(const T &) { + CHECK(false); + return {0}; + } + + template ConstantSubscripts Get(const Constant &x) { + if (dim_) { + return {x.shape().at(*dim_)}; + } else { + return x.shape(); + } + } + + template ConstantSubscripts Get(const Parentheses &x) { + return Get(x.left()); + } + + template ConstantSubscripts Get(const Expr &x) { + // recurse through Expr'a until we hit a Constant + return std::visit([&](const auto &inner) { return Get(inner); }, x.u); + } + +private: + const std::optional dim_; +}; + // Class to retrieve the constant bound of an expression which is an // array that devolves to a type of Constant class GetConstantArrayBoundHelper { @@ -73,9 +104,13 @@ } template ConstantSubscripts Get(const Parentheses &x) { - // LBOUND for (x) is [1, ..., 1] cause of temp variable inside - // parentheses (lower bound is omitted, the default value is 1). - return ConstantSubscripts(x.Rank(), ConstantSubscript{1}); + // Cause of temp variable inside parentheses - return [1, ... 1] for lower + // bounds and shape for upper bounds + if (getLbound_) { + return ConstantSubscripts(x.Rank(), ConstantSubscript{1}); + } else { + return GetConstantArrayShapeHelper{dim_}.Get(x); + } } template ConstantSubscripts Get(const Expr &x) { Index: flang/test/Evaluate/folding08.f90 =================================================================== --- flang/test/Evaluate/folding08.f90 +++ flang/test/Evaluate/folding08.f90 @@ -105,33 +105,45 @@ ubound(a3, 2) == 1 .and. & ubound(a3, 3) == 6 end subroutine - subroutine test4_lbound_parentheses - ! Test lbound with (x) expressions + subroutine test4_bound_parentheses + ! Test [ul]bound with (x) expressions integer :: a1(1) = 0 logical, parameter :: test_lba1 = all(lbound((a1)) == [1]) + logical, parameter :: test_uba1 = all(ubound((a1)) == [1]) integer :: a2(0:2) = 0 logical, parameter :: test_lba2 = all(lbound((a2)) == [1]) + logical, parameter :: test_uba2 = all(ubound((a2)) == [3]) integer :: a3(-1:0) = 0 logical, parameter :: test_lba3 = all(lbound((a3)) == [1]) + logical, parameter :: test_uba3 = all(ubound((a3)) == [2]) integer :: a4(-5:-1, 2:5) = 0 logical, parameter :: test_lba4 = all(lbound((a4)) == [1, 1]) + logical, parameter :: test_uba4 = all(ubound((a4)) == [5, 4]) ! Exercise with DIM= logical, parameter :: test_lba4_dim = lbound((a4), 1) == 1 .and. & lbound((a4), 2) == 1 + logical, parameter :: test_uba4_dim = ubound((a4), 1) == 5 .and. & + ubound((a4), 2) == 4 ! Exercise with parameter types integer, parameter :: pa1(1) = 0 logical, parameter :: test_lbpa1 = all(lbound((pa1)) == [1]) + logical, parameter :: test_ubpa1 = all(ubound((pa1)) == [1]) integer, parameter :: pa2(0:2) = 0 logical, parameter :: test_lbpa2 = all(lbound((pa2)) == [1]) + logical, parameter :: test_ubpa2 = all(ubound((pa2)) == [3]) integer, parameter :: pa3(-1:0) = 0 logical, parameter :: test_lbpa3 = all(lbound((pa3)) == [1]) + logical, parameter :: test_ubpa3 = all(ubound((pa3)) == [2]) integer, parameter :: pa4(-5:-1, 2:5) = 0 logical, parameter :: test_lbpa4 = all(lbound((pa4)) == [1, 1]) + logical, parameter :: test_ubpa4 = all(ubound((pa4)) == [5, 4]) ! Exercise with DIM= logical, parameter :: test_lbpa4_dim = lbound((pa4), 1) == 1 .and. & lbound((pa4), 2) == 1 + logical, parameter :: test_ubpa4_dim = ubound((pa4), 1) == 5 .and. & + ubound((pa4), 2) == 4 end end