Skip to content

Commit

Permalink
[flang] Re-land PR#97337
Browse files Browse the repository at this point in the history
Pull request llvm#97337 was
reverted by llvm#98612 due
to two failing tests in llvm-test-suite -- which I ran, as always,
but must have bungled or misinterpreted (mea culpa).

The failing tests were llvm-test-suite/Fortran/gfortran/regression/
char_length_{20,21}.f90.  They have array constructors with
explicit character types whose dynamic length values are negative
at runtime, which must be interpreted as zero.

This patch extends the original to cover those cases.
  • Loading branch information
klausler committed Jul 12, 2024
1 parent 9f1cfe0 commit e17e3d0
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions flang/lib/Semantics/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ std::optional<Expr<SubscriptInteger>> DynamicTypeWithLength::LEN() const {
}

static std::optional<DynamicTypeWithLength> AnalyzeTypeSpec(
const std::optional<parser::TypeSpec> &spec) {
const std::optional<parser::TypeSpec> &spec, FoldingContext &context) {
if (spec) {
if (const semantics::DeclTypeSpec *typeSpec{spec->declTypeSpec}) {
// Name resolution sets TypeSpec::declTypeSpec only when it's valid
Expand All @@ -80,7 +80,13 @@ static std::optional<DynamicTypeWithLength> AnalyzeTypeSpec(
const semantics::ParamValue &len{cts.length()};
// N.B. CHARACTER(LEN=*) is allowed in type-specs in ALLOCATE() &
// type guards, but not in array constructors.
return DynamicTypeWithLength{DynamicType{kind, len}};
DynamicTypeWithLength type{DynamicType{kind, len}};
if (auto lenExpr{type.LEN()}) {
type.length = Fold(context,
AsExpr(Extremum<SubscriptInteger>{Ordering::Greater,
Expr<SubscriptInteger>{0}, std::move(*lenExpr)}));
}
return type;
} else {
return DynamicTypeWithLength{DynamicType{category, kind}};
}
Expand Down Expand Up @@ -1940,7 +1946,8 @@ MaybeExpr ArrayConstructorContext::ToExpr() {

MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayConstructor &array) {
const parser::AcSpec &acSpec{array.v};
ArrayConstructorContext acContext{*this, AnalyzeTypeSpec(acSpec.type)};
ArrayConstructorContext acContext{
*this, AnalyzeTypeSpec(acSpec.type, GetFoldingContext())};
for (const parser::AcValue &value : acSpec.values) {
acContext.Add(value);
}
Expand Down

0 comments on commit e17e3d0

Please sign in to comment.