diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -236,7 +236,7 @@ // a pointer to the Symbol with TypeParamDetails. template const Symbol *ExtractBareLenParameter(const A &expr) { if (const auto *typeParam{ - evaluate::UnwrapConvertedExpr(expr)}) { + UnwrapConvertedExpr(expr)}) { if (!typeParam->base()) { const Symbol &symbol{typeParam->parameter()}; if (const auto *tpd{symbol.detailsIf()}) { diff --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp --- a/flang/lib/Evaluate/variable.cpp +++ b/flang/lib/Evaluate/variable.cpp @@ -264,14 +264,19 @@ if (const auto *chExpr{UnwrapExpr>(assoc->expr())}) { return chExpr->LEN(); } - } else if (auto dyType{DynamicType::From(ultimate)}) { + } + if (auto dyType{DynamicType::From(ultimate)}) { if (auto len{dyType->GetCharLength()}) { - return len; - } else if (IsDescriptor(ultimate) && !ultimate.owner().IsDerivedType()) { - return Expr{DescriptorInquiry{ - NamedEntity{symbol}, DescriptorInquiry::Field::Len}}; + if (ultimate.owner().IsDerivedType() || IsScopeInvariantExpr(*len)) { + return AsExpr(Extremum{ + Ordering::Greater, Expr{0}, std::move(*len)}); + } } } + if (IsDescriptor(ultimate) && !ultimate.owner().IsDerivedType()) { + return Expr{ + DescriptorInquiry{NamedEntity{symbol}, DescriptorInquiry::Field::Len}}; + } return std::nullopt; } diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp --- a/flang/lib/Semantics/runtime-type-info.cpp +++ b/flang/lib/Semantics/runtime-type-info.cpp @@ -679,6 +679,14 @@ len = Fold(foldingContext, std::move(len)); } if (dyType.category() == TypeCategory::Character && len) { + // Ignore IDIM(x) (represented as MAX(0, x)) + if (const auto *clamped{evaluate::UnwrapExpr< + evaluate::Extremum>(*len)}) { + if (clamped->ordering == evaluate::Ordering::Greater && + clamped->left() == evaluate::Expr{0}) { + len = clamped->right(); + } + } AddValue(values, componentSchema_, "characterlen"s, evaluate::AsGenericExpr(GetValue(len, parameters))); } else {