Skip to content

Commit 936481f

Browse files
authored
[flang] Use LHS type for RHS BOZ on assignment (#139626)
F'2023 allows the right-hand side of an assignment to an integer or real scalar to be a BOZ literal constant; this has already been supported in some compilers. The type of the left-hand side variable is used to convert the value of the BOZ.
1 parent 53f0367 commit 936481f

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

flang/lib/Semantics/expression.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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
50405048
void ArgumentAnalyzer::SayNoMatch(const std::string &opr, bool isAssignment) {
50415049
std::string type0{TypeAsFortran(0)};

flang/test/Semantics/boz-rhs.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
! RUN: %flang_fc1 -fdebug-unparse %s | FileCheck %s
2+
double precision dp
3+
integer(8) i64
4+
!CHECK: dp=1._8
5+
dp = z'3ff0000000000000'
6+
!CHECK: i64=-77129852189294865_8
7+
i64 = z'feedfacedeadbeef'
8+
end

0 commit comments

Comments
 (0)