From bc83d1c655c13c58e34515d8efe7784c62012437 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 4 Nov 2022 14:29:49 -0700 Subject: [PATCH] [flang] Enforce restrictions on intrinsic assignment When the left-hand side of an intrinsic assignment statement is polymorphic, the LHS must be a whole allocatable variable or component and may not be a coarray (10.2.2.1p1(1)). Differential Revision: https://reviews.llvm.org/D139049 --- flang/lib/Semantics/expression.cpp | 12 ++++++++++++ flang/test/Semantics/assign11.f90 | 12 ++++++++++++ flang/test/Semantics/call28.f90 | 1 + 3 files changed, 25 insertions(+) create mode 100644 flang/test/Semantics/assign11.f90 diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 1398f59..7b9b367 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -2633,6 +2633,18 @@ const Assignment *ExpressionAnalyzer::Analyze(const parser::AssignmentStmt &x) { if (!procRef) { analyzer.CheckForNullPointer( "in a non-pointer intrinsic assignment statement"); + const Expr &lhs{analyzer.GetExpr(0)}; + if (auto dyType{lhs.GetType()}; + dyType && dyType->IsPolymorphic()) { // 10.2.1.2p1(1) + const Symbol *lastWhole0{UnwrapWholeSymbolOrComponentDataRef(lhs)}; + const Symbol *lastWhole{ + lastWhole0 ? &lastWhole0->GetUltimate() : nullptr}; + if (!lastWhole || !IsAllocatable(*lastWhole)) { + Say("Left-hand side of assignment may not be polymorphic unless assignment is to an entire allocatable"_err_en_US); + } else if (evaluate::IsCoarray(*lastWhole)) { + Say("Left-hand side of assignment may not be polymorphic if it is a coarray"_err_en_US); + } + } } assignment.emplace(analyzer.MoveExpr(0), analyzer.MoveExpr(1)); if (procRef) { diff --git a/flang/test/Semantics/assign11.f90 b/flang/test/Semantics/assign11.f90 new file mode 100644 index 0000000..eaa9533 --- /dev/null +++ b/flang/test/Semantics/assign11.f90 @@ -0,0 +1,12 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! 10.2.1.2p1(1) +program test + class(*), allocatable :: pa + class(*), pointer :: pp + class(*), allocatable :: pac[:] + pa = 1 ! ok + !ERROR: Left-hand side of assignment may not be polymorphic unless assignment is to an entire allocatable + pp = 1 + !ERROR: Left-hand side of assignment may not be polymorphic if it is a coarray + pac = 1 +end diff --git a/flang/test/Semantics/call28.f90 b/flang/test/Semantics/call28.f90 index 4b7a52e..51430853 100644 --- a/flang/test/Semantics/call28.f90 +++ b/flang/test/Semantics/call28.f90 @@ -11,6 +11,7 @@ module m1 end subroutine pure subroutine s2(x) class(t), intent(in out) :: x + !ERROR: Left-hand side of assignment may not be polymorphic unless assignment is to an entire allocatable !ERROR: Left-hand side of assignment is not definable !BECAUSE: 'x' is polymorphic in a pure subprogram x = t() -- 2.7.4