diff --git a/flang/include/flang/Evaluate/check-expression.h b/flang/include/flang/Evaluate/check-expression.h --- a/flang/include/flang/Evaluate/check-expression.h +++ b/flang/include/flang/Evaluate/check-expression.h @@ -110,6 +110,8 @@ const ComplexPart &, FoldingContext &); extern template std::optional IsContiguous( const CoarrayRef &, FoldingContext &); +extern template std::optional IsContiguous( + const Symbol &, FoldingContext &); template bool IsSimplyContiguous(const A &x, FoldingContext &context) { return IsContiguous(x, context).value_or(false); diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp --- a/flang/lib/Evaluate/check-expression.cpp +++ b/flang/lib/Evaluate/check-expression.cpp @@ -768,11 +768,10 @@ } else if (ultimate.has()) { return Base::operator()(ultimate); // use expr } else if (semantics::IsPointer(ultimate) || - semantics::IsAssumedShape(ultimate)) { + semantics::IsAssumedShape(ultimate) || IsAssumedRank(ultimate)) { return std::nullopt; - } else if (const auto *details{ - ultimate.detailsIf()}) { - return !details->IsAssumedRank(); + } else if (ultimate.has()) { + return true; } else { return Base::operator()(ultimate); } @@ -936,6 +935,7 @@ template std::optional IsContiguous( const ComplexPart &, FoldingContext &); template std::optional IsContiguous(const CoarrayRef &, FoldingContext &); +template std::optional IsContiguous(const Symbol &, FoldingContext &); // IsErrorExpr() struct IsErrorExprHelper : public AnyTraverse { diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp --- a/flang/lib/Evaluate/fold-logical.cpp +++ b/flang/lib/Evaluate/fold-logical.cpp @@ -187,6 +187,10 @@ if (auto contiguous{IsContiguous(*expr, context)}) { return Expr{*contiguous}; } + } else if (auto *assumedType{args[0]->GetAssumedTypeDummy()}) { + if (auto contiguous{IsContiguous(*assumedType, context)}) { + return Expr{*contiguous}; + } } } } else if (name == "lge" || name == "lgt" || name == "lle" || name == "llt") { diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -586,9 +586,8 @@ symbol.name()); } if (details.IsArray() && details.shape().IsExplicitShape()) { - messages_.Say( - "Assumed-type array argument 'arg8' must be assumed shape," - " assumed size, or assumed rank"_err_en_US, + messages_.Say("Assumed-type array argument '%s' must be assumed shape," + " assumed size, or assumed rank"_err_en_US, symbol.name()); } } diff --git a/flang/test/Evaluate/rewrite03.f90 b/flang/test/Evaluate/rewrite03.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Evaluate/rewrite03.f90 @@ -0,0 +1,19 @@ +! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +! Tests rewrite of IS_CONTIGUOUS with TYPE(*) arguments. + +subroutine test_is_contiguous(assumed_size, assumed_shape, & + & assumed_shape_contiguous, assumed_rank, assumed_rank_contiguous) + type(*) :: assumed_size(*), assumed_shape(:), assumed_shape_contiguous(:) + type(*) :: assumed_rank(..), assumed_rank_contiguous(..) + contiguous :: assumed_shape_contiguous, assumed_rank_contiguous +! CHECK: PRINT *, .true._4 + print *, is_contiguous(assumed_size) +! CHECK: PRINT *, .true._4 + print *, is_contiguous(assumed_shape_contiguous) +! CHECK: PRINT *, .true._4 + print *, is_contiguous(assumed_rank_contiguous) +! CHECK: PRINT *, is_contiguous(assumed_shape) + print *, is_contiguous(assumed_shape) +! CHECK: PRINT *, is_contiguous(assumed_rank) + print *, is_contiguous(assumed_rank) +end subroutine