@@ -141,7 +141,7 @@ class ArgumentAnalyzer {
141141 }
142142 void Analyze (const parser::Variable &);
143143 void Analyze (const parser::ActualArgSpec &, bool isSubroutine);
144- void ConvertBOZ (std::optional<DynamicType> & thisType, std::size_t i ,
144+ void ConvertBOZ (std::optional<DynamicType> * thisType, std::size_t ,
145145 std::optional<DynamicType> otherType);
146146
147147 bool IsIntrinsicRelational (
@@ -3573,8 +3573,8 @@ MaybeExpr RelationHelper(ExpressionAnalyzer &context, RelationalOperator opr,
35733573 if (!analyzer.fatalErrors ()) {
35743574 std::optional<DynamicType> leftType{analyzer.GetType (0 )};
35753575 std::optional<DynamicType> rightType{analyzer.GetType (1 )};
3576- analyzer.ConvertBOZ (leftType, 0 , rightType);
3577- analyzer.ConvertBOZ (rightType, 1 , leftType);
3576+ analyzer.ConvertBOZ (& leftType, 0 , rightType);
3577+ analyzer.ConvertBOZ (& rightType, 1 , leftType);
35783578 if (leftType && rightType &&
35793579 analyzer.IsIntrinsicRelational (opr, *leftType, *rightType)) {
35803580 analyzer.CheckForNullPointer (" as a relational operand" );
@@ -4488,9 +4488,22 @@ std::optional<ProcedureRef> ArgumentAnalyzer::TryDefinedAssignment() {
44884488 // allocatable (the explicit conversion would prevent the propagation of the
44894489 // right hand side if it is a variable). Lowering will deal with the
44904490 // conversion in this case.
4491- if (lhsType && rhsType &&
4492- (!IsAllocatableDesignator (lhs) || context_.inWhereBody ())) {
4493- AddAssignmentConversion (*lhsType, *rhsType);
4491+ if (lhsType) {
4492+ if (rhsType) {
4493+ if (!IsAllocatableDesignator (lhs) || context_.inWhereBody ()) {
4494+ AddAssignmentConversion (*lhsType, *rhsType);
4495+ }
4496+ } else {
4497+ if (lhsType->category () == TypeCategory::Integer ||
4498+ lhsType->category () == TypeCategory::Real) {
4499+ ConvertBOZ (nullptr , 1 , lhsType);
4500+ }
4501+ if (IsBOZLiteral (1 )) {
4502+ context_.Say (
4503+ " Right-hand side of this assignment may not be BOZ" _err_en_US);
4504+ fatalErrors_ = true ;
4505+ }
4506+ }
44944507 }
44954508 if (!fatalErrors_) {
44964509 CheckAssignmentConformance ();
@@ -4719,7 +4732,7 @@ int ArgumentAnalyzer::GetRank(std::size_t i) const {
47194732// otherType. If it's REAL convert to REAL, otherwise convert to INTEGER.
47204733// Note that IBM supports comparing BOZ literals to CHARACTER operands. That
47214734// is not currently supported.
4722- void ArgumentAnalyzer::ConvertBOZ (std::optional<DynamicType> & thisType,
4735+ void ArgumentAnalyzer::ConvertBOZ (std::optional<DynamicType> * thisType,
47234736 std::size_t i, std::optional<DynamicType> otherType) {
47244737 if (IsBOZLiteral (i)) {
47254738 Expr<SomeType> &&argExpr{MoveExpr (i)};
@@ -4729,13 +4742,17 @@ void ArgumentAnalyzer::ConvertBOZ(std::optional<DynamicType> &thisType,
47294742 MaybeExpr realExpr{
47304743 ConvertToKind<TypeCategory::Real>(kind, std::move (*boz))};
47314744 actuals_[i] = std::move (*realExpr);
4732- thisType.emplace (TypeCategory::Real, kind);
4745+ if (thisType) {
4746+ thisType->emplace (TypeCategory::Real, kind);
4747+ }
47334748 } else {
47344749 int kind{context_.context ().GetDefaultKind (TypeCategory::Integer)};
47354750 MaybeExpr intExpr{
47364751 ConvertToKind<TypeCategory::Integer>(kind, std::move (*boz))};
47374752 actuals_[i] = std::move (*intExpr);
4738- thisType.emplace (TypeCategory::Integer, kind);
4753+ if (thisType) {
4754+ thisType->emplace (TypeCategory::Integer, kind);
4755+ }
47394756 }
47404757 }
47414758}
0 commit comments