Skip to content

Commit 78d6009

Browse files
committed
[flang] Deal with negative character lengths in semantics
Fortran defines LEN(X) = 0 after CHARACTER(LEN=-1)::X so apply MAX(0, ...) to character length expressions. Differential Revision: https://reviews.llvm.org/D114030
1 parent 1e9fa0b commit 78d6009

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ auto UnwrapConvertedExpr(B &x) -> common::Constify<A, B> * {
236236
// a pointer to the Symbol with TypeParamDetails.
237237
template <typename A> const Symbol *ExtractBareLenParameter(const A &expr) {
238238
if (const auto *typeParam{
239-
evaluate::UnwrapConvertedExpr<evaluate::TypeParamInquiry>(expr)}) {
239+
UnwrapConvertedExpr<evaluate::TypeParamInquiry>(expr)}) {
240240
if (!typeParam->base()) {
241241
const Symbol &symbol{typeParam->parameter()};
242242
if (const auto *tpd{symbol.detailsIf<semantics::TypeParamDetails>()}) {

flang/lib/Evaluate/variable.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,19 @@ static std::optional<Expr<SubscriptInteger>> SymbolLEN(const Symbol &symbol) {
264264
if (const auto *chExpr{UnwrapExpr<Expr<SomeCharacter>>(assoc->expr())}) {
265265
return chExpr->LEN();
266266
}
267-
} else if (auto dyType{DynamicType::From(ultimate)}) {
267+
}
268+
if (auto dyType{DynamicType::From(ultimate)}) {
268269
if (auto len{dyType->GetCharLength()}) {
269-
return len;
270-
} else if (IsDescriptor(ultimate) && !ultimate.owner().IsDerivedType()) {
271-
return Expr<SubscriptInteger>{DescriptorInquiry{
272-
NamedEntity{symbol}, DescriptorInquiry::Field::Len}};
270+
if (ultimate.owner().IsDerivedType() || IsScopeInvariantExpr(*len)) {
271+
return AsExpr(Extremum<SubscriptInteger>{
272+
Ordering::Greater, Expr<SubscriptInteger>{0}, std::move(*len)});
273+
}
273274
}
274275
}
276+
if (IsDescriptor(ultimate) && !ultimate.owner().IsDerivedType()) {
277+
return Expr<SubscriptInteger>{
278+
DescriptorInquiry{NamedEntity{symbol}, DescriptorInquiry::Field::Len}};
279+
}
275280
return std::nullopt;
276281
}
277282

flang/lib/Semantics/runtime-type-info.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,14 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
679679
len = Fold(foldingContext, std::move(len));
680680
}
681681
if (dyType.category() == TypeCategory::Character && len) {
682+
// Ignore IDIM(x) (represented as MAX(0, x))
683+
if (const auto *clamped{evaluate::UnwrapExpr<
684+
evaluate::Extremum<evaluate::SubscriptInteger>>(*len)}) {
685+
if (clamped->ordering == evaluate::Ordering::Greater &&
686+
clamped->left() == evaluate::Expr<evaluate::SubscriptInteger>{0}) {
687+
len = clamped->right();
688+
}
689+
}
682690
AddValue(values, componentSchema_, "characterlen"s,
683691
evaluate::AsGenericExpr(GetValue(len, parameters)));
684692
} else {

0 commit comments

Comments
 (0)