@@ -150,8 +150,9 @@ class ArgumentAnalyzer {
150150 }
151151 void Analyze (const parser::Variable &);
152152 void Analyze (const parser::ActualArgSpec &, bool isSubroutine);
153- void ConvertBOZ (std::optional<DynamicType> *thisType, std::size_t ,
153+ void ConvertBOZOperand (std::optional<DynamicType> *thisType, std::size_t ,
154154 std::optional<DynamicType> otherType);
155+ void ConvertBOZAssignmentRHS (const DynamicType &lhsType);
155156
156157 bool IsIntrinsicRelational (
157158 RelationalOperator, const DynamicType &, const DynamicType &) const ;
@@ -3849,8 +3850,8 @@ MaybeExpr RelationHelper(ExpressionAnalyzer &context, RelationalOperator opr,
38493850 if (!analyzer.fatalErrors ()) {
38503851 std::optional<DynamicType> leftType{analyzer.GetType (0 )};
38513852 std::optional<DynamicType> rightType{analyzer.GetType (1 )};
3852- analyzer.ConvertBOZ (&leftType, 0 , rightType);
3853- analyzer.ConvertBOZ (&rightType, 1 , leftType);
3853+ analyzer.ConvertBOZOperand (&leftType, 0 , rightType);
3854+ analyzer.ConvertBOZOperand (&rightType, 1 , leftType);
38543855 if (leftType && rightType &&
38553856 analyzer.IsIntrinsicRelational (opr, *leftType, *rightType)) {
38563857 analyzer.CheckForNullPointer (" as a relational operand" );
@@ -4761,12 +4762,8 @@ std::optional<ProcedureRef> ArgumentAnalyzer::TryDefinedAssignment() {
47614762 if (!IsAllocatableDesignator (lhs) || context_.inWhereBody ()) {
47624763 AddAssignmentConversion (*lhsType, *rhsType);
47634764 }
4764- } else {
4765- if (lhsType->category () == TypeCategory::Integer ||
4766- lhsType->category () == TypeCategory::Unsigned ||
4767- lhsType->category () == TypeCategory::Real) {
4768- ConvertBOZ (nullptr , 1 , lhsType);
4769- }
4765+ } else if (IsBOZLiteral (1 )) {
4766+ ConvertBOZAssignmentRHS (*lhsType);
47704767 if (IsBOZLiteral (1 )) {
47714768 context_.Say (
47724769 " Right-hand side of this assignment may not be BOZ" _err_en_US);
@@ -5003,7 +5000,7 @@ int ArgumentAnalyzer::GetRank(std::size_t i) const {
50035000// UNSIGNED; otherwise, convert to INTEGER.
50045001// Note that IBM supports comparing BOZ literals to CHARACTER operands. That
50055002// is not currently supported.
5006- void ArgumentAnalyzer::ConvertBOZ (std::optional<DynamicType> *thisType,
5003+ void ArgumentAnalyzer::ConvertBOZOperand (std::optional<DynamicType> *thisType,
50075004 std::size_t i, std::optional<DynamicType> otherType) {
50085005 if (IsBOZLiteral (i)) {
50095006 Expr<SomeType> &&argExpr{MoveExpr (i)};
@@ -5036,6 +5033,17 @@ void ArgumentAnalyzer::ConvertBOZ(std::optional<DynamicType> *thisType,
50365033 }
50375034}
50385035
5036+ void ArgumentAnalyzer::ConvertBOZAssignmentRHS (const DynamicType &lhsType) {
5037+ if (lhsType.category () == TypeCategory::Integer ||
5038+ lhsType.category () == TypeCategory::Unsigned ||
5039+ lhsType.category () == TypeCategory::Real) {
5040+ Expr<SomeType> rhs{MoveExpr (1 )};
5041+ if (MaybeExpr converted{ConvertToType (lhsType, std::move (rhs))}) {
5042+ actuals_[1 ] = std::move (*converted);
5043+ }
5044+ }
5045+ }
5046+
50395047// Report error resolving opr when there is a user-defined one available
50405048void ArgumentAnalyzer::SayNoMatch (const std::string &opr, bool isAssignment) {
50415049 std::string type0{TypeAsFortran (0 )};
0 commit comments