diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h index 068395072266f..eee23dba4831f 100644 --- a/flang/include/flang/Semantics/expression.h +++ b/flang/include/flang/Semantics/expression.h @@ -257,6 +257,7 @@ class ExpressionAnalyzer { // Builds a typed Designator from an untyped DataRef MaybeExpr Designate(DataRef &&); + void CheckForWholeAssumedSizeArray(parser::CharBlock, const Symbol *); // Allows a whole assumed-size array to appear for the lifetime of // the returned value. diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 5e77cde93bbff..f2b9702d7c5a0 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -1077,20 +1077,24 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) { n.symbol->attrs().reset(semantics::Attr::VOLATILE); } } - if (!isWholeAssumedSizeArrayOk_ && - 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, - n.source), - *n.symbol); - } + CheckForWholeAssumedSizeArray(n.source, n.symbol); return Designate(DataRef{*n.symbol}); } } } +void ExpressionAnalyzer::CheckForWholeAssumedSizeArray( + parser::CharBlock at, const Symbol *symbol) { + if (!isWholeAssumedSizeArrayOk_ && symbol && + semantics::IsAssumedSizeArray(ResolveAssociations(*symbol))) { + AttachDeclaration( + SayAt(at, + "Whole assumed-size array '%s' may not appear here without subscripts"_err_en_US, + symbol->name()), + *symbol); + } +} + MaybeExpr ExpressionAnalyzer::Analyze(const parser::NamedConstant &n) { auto restorer{GetContextualMessages().SetLocation(n.v.source)}; if (MaybeExpr value{Analyze(n.v)}) { @@ -3362,7 +3366,8 @@ const Assignment *ExpressionAnalyzer::Analyze(const parser::AssignmentStmt &x) { ArgumentAnalyzer analyzer{*this}; const auto &variable{std::get(x.t)}; analyzer.Analyze(variable); - analyzer.Analyze(std::get(x.t)); + const auto &rhsExpr{std::get(x.t)}; + analyzer.Analyze(rhsExpr); std::optional assignment; if (!analyzer.fatalErrors()) { auto restorer{GetContextualMessages().SetLocation(variable.GetSource())}; @@ -3392,6 +3397,8 @@ const Assignment *ExpressionAnalyzer::Analyze(const parser::AssignmentStmt &x) { } } } + CheckForWholeAssumedSizeArray( + rhsExpr.source, UnwrapWholeSymbolDataRef(analyzer.GetExpr(1))); } assignment.emplace(analyzer.MoveExpr(0), analyzer.MoveExpr(1)); if (procRef) { diff --git a/flang/test/Semantics/assign04.f90 b/flang/test/Semantics/assign04.f90 index 14d90a8d5a224..1cea1b6ef14e2 100644 --- a/flang/test/Semantics/assign04.f90 +++ b/flang/test/Semantics/assign04.f90 @@ -99,12 +99,15 @@ subroutine s5() subroutine s6(x) integer :: x(*) + integer, allocatable :: ja(:) x(1:3) = [1, 2, 3] x(:3) = [1, 2, 3] !ERROR: Assumed-size array 'x' must have explicit final subscript upper bound value x(:) = [1, 2, 3] !ERROR: Whole assumed-size array 'x' may not appear here without subscripts x = [1, 2, 3] + !ERROR: Whole assumed-size array 'x' may not appear here without subscripts + ja = x associate (y => x) ! ok !ERROR: Whole assumed-size array 'y' may not appear here without subscripts y = [1, 2, 3]