Skip to content

Commit

Permalink
[flang] Parenthesize RHS arguments to defined assignments (bug #62599)
Browse files Browse the repository at this point in the history
The right-hand sides of assignment statements are always expressions,
never variables.  When an assignment statement is converted into a call
to a defined assignment subroutine, and the actual argument being associated
with the second dummy argument is a variable, and the dummy argument does
not have the VALUE attribute, wrap it with parentheses so that lowering
will pass it by means of a temporary.

Fixes #62599.

Differential Revision: https://reviews.llvm.org/D150331
  • Loading branch information
klausler committed May 16, 2023
1 parent 7c1f279 commit 01e22df
Show file tree
Hide file tree
Showing 4 changed files with 657 additions and 618 deletions.
21 changes: 18 additions & 3 deletions flang/lib/Semantics/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4067,7 +4067,7 @@ bool ArgumentAnalyzer::OkLogicalIntegerAssignment(

std::optional<ProcedureRef> ArgumentAnalyzer::GetDefinedAssignmentProc() {
const Symbol *proc{nullptr};
int passedObjectIndex{-1};
std::optional<int> passedObjectIndex;
std::string oprNameString{"assignment(=)"};
parser::CharBlock oprName{oprNameString};
const auto &scope{context_.context().FindScope(source_)};
Expand Down Expand Up @@ -4099,8 +4099,23 @@ std::optional<ProcedureRef> ArgumentAnalyzer::GetDefinedAssignmentProc() {
return std::nullopt;
}
ActualArguments actualsCopy{actuals_};
if (passedObjectIndex >= 0) {
actualsCopy[passedObjectIndex]->set_isPassedObject();
// Ensure that the RHS argument is not passed as a variable unless
// the dummy argument has the VALUE attribute.
if (evaluate::IsVariable(actualsCopy.at(1).value().UnwrapExpr())) {
auto chars{evaluate::characteristics::Procedure::Characterize(
*proc, context_.GetFoldingContext())};
const auto *rhsDummy{chars && chars->dummyArguments.size() == 2
? std::get_if<evaluate::characteristics::DummyDataObject>(
&chars->dummyArguments.at(1).u)
: nullptr};
if (!rhsDummy ||
!rhsDummy->attrs.test(
evaluate::characteristics::DummyDataObject::Attr::Value)) {
actualsCopy.at(1).value().Parenthesize();
}
}
if (passedObjectIndex) {
actualsCopy[*passedObjectIndex]->set_isPassedObject();
}
return ProcedureRef{ProcedureDesignator{*proc}, std::move(actualsCopy)};
}
Expand Down

0 comments on commit 01e22df

Please sign in to comment.