diff options
Diffstat (limited to 'flang/lib/Semantics/expression.cpp')
-rw-r--r-- | flang/lib/Semantics/expression.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 6047f8da441b..d30465eef86e 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -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_)}; @@ -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)}; } |