Skip to content

Commit

Permalink
[flang] Handle typeless (BOZ) arguments in AreCompatibleTypes()
Browse files Browse the repository at this point in the history
The current code can crash due to the representation's use of a negative
INTEGER kind code to signify a typeless (BOZ) argument's "type" as a
DynamicType.  Detect and handle that case, and change some direct
uses of the kind_ data member into kind() accessor references in
places that shouldn't be confronted with BOZ.

Differential Revision: https://reviews.llvm.org/D159023
  • Loading branch information
klausler committed Aug 29, 2023
1 parent 18c7bf0 commit 72079d9
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions flang/lib/Evaluate/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ std::size_t DynamicType::GetAlignment(
}
}
} else {
return targetCharacteristics.GetAlignment(category_, kind_);
return targetCharacteristics.GetAlignment(category_, kind());
}
return 1; // needs to be after switch to dodge a bogus gcc warning
}
Expand All @@ -193,14 +193,14 @@ std::optional<Expr<SubscriptInteger>> DynamicType::MeasureSizeInBytes(
case TypeCategory::Complex:
case TypeCategory::Logical:
return Expr<SubscriptInteger>{
context.targetCharacteristics().GetByteSize(category_, kind_)};
context.targetCharacteristics().GetByteSize(category_, kind())};
case TypeCategory::Character:
if (auto len{charLength ? Expr<SubscriptInteger>{Constant<SubscriptInteger>{
*charLength}}
: GetCharLength()}) {
return Fold(context,
Expr<SubscriptInteger>{
context.targetCharacteristics().GetByteSize(category_, kind_)} *
context.targetCharacteristics().GetByteSize(category_, kind())} *
std::move(*len));
}
break;
Expand Down Expand Up @@ -540,7 +540,11 @@ static bool AreCompatibleTypes(const DynamicType &x, const DynamicType &y,
return x.kind() == y.kind() &&
(ignoreLengths || !xLen || !yLen || *xLen == *yLen);
} else if (x.category() != TypeCategory::Derived) {
return x.kind() == y.kind();
if (x.IsTypelessIntrinsicArgument()) {
return y.IsTypelessIntrinsicArgument();
} else {
return !y.IsTypelessIntrinsicArgument() && x.kind() == y.kind();
}
} else {
const auto *xdt{GetDerivedTypeSpec(x)};
const auto *ydt{GetDerivedTypeSpec(y)};
Expand Down Expand Up @@ -651,7 +655,7 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
case TypeCategory::Integer:
switch (that.category_) {
case TypeCategory::Integer:
return DynamicType{TypeCategory::Integer, std::max(kind_, that.kind_)};
return DynamicType{TypeCategory::Integer, std::max(kind(), that.kind())};
case TypeCategory::Real:
case TypeCategory::Complex:
return that;
Expand All @@ -664,9 +668,9 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
case TypeCategory::Integer:
return *this;
case TypeCategory::Real:
return DynamicType{TypeCategory::Real, std::max(kind_, that.kind_)};
return DynamicType{TypeCategory::Real, std::max(kind(), that.kind())};
case TypeCategory::Complex:
return DynamicType{TypeCategory::Complex, std::max(kind_, that.kind_)};
return DynamicType{TypeCategory::Complex, std::max(kind(), that.kind())};
default:
CRASH_NO_CASE;
}
Expand All @@ -677,15 +681,15 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
return *this;
case TypeCategory::Real:
case TypeCategory::Complex:
return DynamicType{TypeCategory::Complex, std::max(kind_, that.kind_)};
return DynamicType{TypeCategory::Complex, std::max(kind(), that.kind())};
default:
CRASH_NO_CASE;
}
break;
case TypeCategory::Logical:
switch (that.category_) {
case TypeCategory::Logical:
return DynamicType{TypeCategory::Logical, std::max(kind_, that.kind_)};
return DynamicType{TypeCategory::Logical, std::max(kind(), that.kind())};
default:
CRASH_NO_CASE;
}
Expand Down

0 comments on commit 72079d9

Please sign in to comment.