@@ -141,7 +141,7 @@ class ArgumentAnalyzer {
141
141
}
142
142
void Analyze (const parser::Variable &);
143
143
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 ,
145
145
std::optional<DynamicType> otherType);
146
146
147
147
bool IsIntrinsicRelational (
@@ -3573,8 +3573,8 @@ MaybeExpr RelationHelper(ExpressionAnalyzer &context, RelationalOperator opr,
3573
3573
if (!analyzer.fatalErrors ()) {
3574
3574
std::optional<DynamicType> leftType{analyzer.GetType (0 )};
3575
3575
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);
3578
3578
if (leftType && rightType &&
3579
3579
analyzer.IsIntrinsicRelational (opr, *leftType, *rightType)) {
3580
3580
analyzer.CheckForNullPointer (" as a relational operand" );
@@ -4488,9 +4488,22 @@ std::optional<ProcedureRef> ArgumentAnalyzer::TryDefinedAssignment() {
4488
4488
// allocatable (the explicit conversion would prevent the propagation of the
4489
4489
// right hand side if it is a variable). Lowering will deal with the
4490
4490
// 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
+ }
4494
4507
}
4495
4508
if (!fatalErrors_) {
4496
4509
CheckAssignmentConformance ();
@@ -4719,7 +4732,7 @@ int ArgumentAnalyzer::GetRank(std::size_t i) const {
4719
4732
// otherType. If it's REAL convert to REAL, otherwise convert to INTEGER.
4720
4733
// Note that IBM supports comparing BOZ literals to CHARACTER operands. That
4721
4734
// is not currently supported.
4722
- void ArgumentAnalyzer::ConvertBOZ (std::optional<DynamicType> & thisType,
4735
+ void ArgumentAnalyzer::ConvertBOZ (std::optional<DynamicType> * thisType,
4723
4736
std::size_t i, std::optional<DynamicType> otherType) {
4724
4737
if (IsBOZLiteral (i)) {
4725
4738
Expr<SomeType> &&argExpr{MoveExpr (i)};
@@ -4729,13 +4742,17 @@ void ArgumentAnalyzer::ConvertBOZ(std::optional<DynamicType> &thisType,
4729
4742
MaybeExpr realExpr{
4730
4743
ConvertToKind<TypeCategory::Real>(kind, std::move (*boz))};
4731
4744
actuals_[i] = std::move (*realExpr);
4732
- thisType.emplace (TypeCategory::Real, kind);
4745
+ if (thisType) {
4746
+ thisType->emplace (TypeCategory::Real, kind);
4747
+ }
4733
4748
} else {
4734
4749
int kind{context_.context ().GetDefaultKind (TypeCategory::Integer)};
4735
4750
MaybeExpr intExpr{
4736
4751
ConvertToKind<TypeCategory::Integer>(kind, std::move (*boz))};
4737
4752
actuals_[i] = std::move (*intExpr);
4738
- thisType.emplace (TypeCategory::Integer, kind);
4753
+ if (thisType) {
4754
+ thisType->emplace (TypeCategory::Integer, kind);
4755
+ }
4739
4756
}
4740
4757
}
4741
4758
}
0 commit comments