diff --git a/flang/include/flang/Semantics/type.h b/flang/include/flang/Semantics/type.h --- a/flang/include/flang/Semantics/type.h +++ b/flang/include/flang/Semantics/type.h @@ -223,6 +223,7 @@ bool IsImpliedShape() const; bool IsAssumedSize() const; bool IsAssumedRank() const; + bool IsConstantShape() const; // explicit shape with constant bounds private: // Check non-empty and predicate is true for each element. diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp --- a/flang/lib/Evaluate/type.cpp +++ b/flang/lib/Evaluate/type.cpp @@ -31,13 +31,8 @@ } } } - if (details.IsAssumedShape() || details.IsDeferredShape() || - details.IsAssumedRank()) { - return true; - } - // TODO: Explicit shape component array dependent on length parameter // TODO: Automatic (adjustable) arrays - are they descriptors? - return false; + return !details.shape().empty() && !details.shape().IsConstantShape(); } static bool IsDescriptor(const ProcEntityDetails &details) { diff --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp --- a/flang/lib/Semantics/type.cpp +++ b/flang/lib/Semantics/type.cpp @@ -507,6 +507,13 @@ bool ArraySpec::IsAssumedRank() const { return Rank() == 1 && front().lbound().isAssumed(); } +bool ArraySpec::IsConstantShape() const { + return CheckAll([](const ShapeSpec &x) { + const auto &lb{x.lbound().GetExplicit()}; + const auto &ub{x.ubound().GetExplicit()}; + return lb && ub && IsConstantExpr(*lb) && IsConstantExpr(*ub); + }); +} llvm::raw_ostream &operator<<( llvm::raw_ostream &os, const ArraySpec &arraySpec) { diff --git a/flang/test/Semantics/offsets01.f90 b/flang/test/Semantics/offsets01.f90 --- a/flang/test/Semantics/offsets01.f90 +++ b/flang/test/Semantics/offsets01.f90 @@ -49,4 +49,6 @@ end type type(t1(n)) :: x1 !CHECK: x1 size=48 offset= type(t2(n,n)) :: x2 !CHECK: x2 size=56 offset= + !CHECK: a size=48 offset=0: + !CHECK: b size=72 offset=0: end