[flang] Perform definability checks on LHS of assignment
If the pure context check succeeds, call `WhyNotModifiable` to verify the LHS can be modified. Detect assignment to whole assumed-size array. Change `IsVariable` to return false for a parameter or a component or array reference whose base it a parameter. When analyzing an assignment statement, report an error if the LHS is a constant expression. Otherwise it might get folded and when we detect the problem later the error will be confusing. Handle Substring on LHS of assignment. Change ExtractDataRef and IsVariable to work on a Substring. Fix IsImpliedShape and IsAssumedSize predicates in ArraySpec. Fix C709 check in check-declarations.cpp. Original-commit: flang-compiler/f18@f2d2657aab Reviewed-on: https://github.com/flang-compiler/f18/pull/1050
This commit is contained in:
@@ -66,10 +66,23 @@ void AssignmentContext::Analyze(const parser::AssignmentStmt &stmt) {
|
||||
const SomeExpr &rhs{assignment->rhs};
|
||||
auto lhsLoc{std::get<parser::Variable>(stmt.t).GetSource()};
|
||||
auto rhsLoc{std::get<parser::Expr>(stmt.t).source};
|
||||
auto shape{evaluate::GetShape(foldingContext(), lhs)};
|
||||
if (shape && !shape->empty() && !shape->back().has_value()) { // C1014
|
||||
Say(lhsLoc,
|
||||
"Left-hand side of assignment may not be a whole assumed-size array"_err_en_US);
|
||||
}
|
||||
if (CheckForPureContext(lhs, rhs, rhsLoc, false)) {
|
||||
const Scope &scope{context_.FindScope(lhsLoc)};
|
||||
if (auto whyNot{WhyNotModifiable(lhsLoc, lhs, scope)}) {
|
||||
if (auto *msg{Say(lhsLoc,
|
||||
"Left-hand side of assignment is not modifiable"_err_en_US)}) {
|
||||
msg->Attach(*whyNot);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (whereDepth_ > 0) {
|
||||
CheckShape(lhsLoc, &lhs);
|
||||
}
|
||||
CheckForPureContext(lhs, rhs, rhsLoc, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +182,8 @@ bool AssignmentContext::CheckForPureContext(const SomeExpr &lhs,
|
||||
// ASSOCIATE(a=>x) -- check x, not a, for "a=..."
|
||||
base = dataRef ? &dataRef->GetFirstSymbol() : nullptr;
|
||||
}
|
||||
if (!CheckDefinabilityInPureScope(messages, *base, scope, *pure)) {
|
||||
if (base &&
|
||||
!CheckDefinabilityInPureScope(messages, *base, scope, *pure)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user