From 147f54e36a182934d926bc311a5d63c64425664f Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:08:45 -0800 Subject: [PATCH] [flang] Accept whole assumed-size arrays as variable selectors (#82806) Include variable selectors ("select type (x => y)") as a context in which a whole assumed-size array may legitimately appear. Fixes https://github.com/llvm/llvm-project/issues/81910. --- flang/lib/Semantics/expression.cpp | 37 ++++++++++++++++++++++-------- flang/test/Semantics/assign04.f90 | 7 ++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 0132562bc6c90..54bfe0f2e1563 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -973,7 +973,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) { } } if (!isWholeAssumedSizeArrayOk_ && - semantics::IsAssumedSizeArray(*n.symbol)) { // C1002, C1014, C1231 + semantics::IsAssumedSizeArray( + ResolveAssociations(*n.symbol))) { // C1002, C1014, C1231 AttachDeclaration( SayAt(n, "Whole assumed-size array '%s' may not appear here without subscripts"_err_en_US, @@ -1329,15 +1330,29 @@ std::optional ExpressionAnalyzer::CreateComponent(DataRef &&base, // Derived type component references and type parameter inquiries MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) { - MaybeExpr base{Analyze(sc.base)}; Symbol *sym{sc.component.symbol}; - if (!base || !sym || context_.HasError(sym)) { + if (context_.HasError(sym)) { + return std::nullopt; + } + const auto *misc{sym->detailsIf()}; + bool isTypeParamInquiry{sym->has() || + (misc && + (misc->kind() == semantics::MiscDetails::Kind::KindParamInquiry || + misc->kind() == semantics::MiscDetails::Kind::LenParamInquiry))}; + MaybeExpr base; + if (isTypeParamInquiry) { + auto restorer{AllowWholeAssumedSizeArray()}; + base = Analyze(sc.base); + } else { + base = Analyze(sc.base); + } + if (!base) { return std::nullopt; } const auto &name{sc.component.source}; if (auto *dtExpr{UnwrapExpr>(*base)}) { const auto *dtSpec{GetDerivedTypeSpec(dtExpr->GetType())}; - if (sym->detailsIf()) { + if (isTypeParamInquiry) { if (auto *designator{UnwrapExpr>(*dtExpr)}) { if (std::optional dyType{DynamicType::From(*sym)}) { if (dyType->category() == TypeCategory::Integer) { @@ -1350,8 +1365,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) { Say(name, "Type parameter is not INTEGER"_err_en_US); } else { Say(name, - "A type parameter inquiry must be applied to " - "a designator"_err_en_US); + "A type parameter inquiry must be applied to a designator"_err_en_US); } } else if (!dtSpec || !dtSpec->scope()) { CHECK(context_.AnyFatalError() || !foldingContext_.messages().empty()); @@ -1393,8 +1407,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) { return AsGenericExpr(std::move(realExpr)); } } - } else if (kind == MiscKind::KindParamInquiry || - kind == MiscKind::LenParamInquiry) { + } else if (isTypeParamInquiry) { // %kind or %len ActualArgument arg{std::move(*base)}; SetArgSourceLocation(arg, name); return MakeFunctionRef(name, ActualArguments{std::move(arg)}); @@ -3743,9 +3756,12 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Selector &selector) { } } } + // Not a Variable -> FunctionReference + auto restorer{AllowWholeAssumedSizeArray()}; + return Analyze(selector.u); + } else { // Expr + return Analyze(selector.u); } - // Not a Variable -> FunctionReference; handle normally as Variable or Expr - return Analyze(selector.u); } MaybeExpr ExpressionAnalyzer::Analyze(const parser::DataStmtConstant &x) { @@ -4001,6 +4017,7 @@ void ArgumentAnalyzer::Analyze( const parser::ActualArgSpec &arg, bool isSubroutine) { // TODO: C1534: Don't allow a "restricted" specific intrinsic to be passed. std::optional actual; + auto restorer{context_.AllowWholeAssumedSizeArray()}; common::visit( common::visitors{ [&](const common::Indirection &x) { diff --git a/flang/test/Semantics/assign04.f90 b/flang/test/Semantics/assign04.f90 index a00ca5213a7aa..14d90a8d5a224 100644 --- a/flang/test/Semantics/assign04.f90 +++ b/flang/test/Semantics/assign04.f90 @@ -105,6 +105,13 @@ subroutine s6(x) x(:) = [1, 2, 3] !ERROR: Whole assumed-size array 'x' may not appear here without subscripts x = [1, 2, 3] + associate (y => x) ! ok + !ERROR: Whole assumed-size array 'y' may not appear here without subscripts + y = [1, 2, 3] + end associate + !ERROR: Whole assumed-size array 'x' may not appear here without subscripts + associate (y => (x)) + end associate end module m7