Skip to content

Commit 7f06560

Browse files
authored
[flang] Re-land PR#97337 (#98656)
Pull request #97337 was reverted by #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.
1 parent 1e96b4a commit 7f06560

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

flang/lib/Semantics/expression.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ std::optional<Expr<SubscriptInteger>> DynamicTypeWithLength::LEN() const {
6363
}
6464

6565
static std::optional<DynamicTypeWithLength> AnalyzeTypeSpec(
66-
const std::optional<parser::TypeSpec> &spec) {
66+
const std::optional<parser::TypeSpec> &spec, FoldingContext &context) {
6767
if (spec) {
6868
if (const semantics::DeclTypeSpec *typeSpec{spec->declTypeSpec}) {
6969
// Name resolution sets TypeSpec::declTypeSpec only when it's valid
@@ -80,7 +80,13 @@ static std::optional<DynamicTypeWithLength> AnalyzeTypeSpec(
8080
const semantics::ParamValue &len{cts.length()};
8181
// N.B. CHARACTER(LEN=*) is allowed in type-specs in ALLOCATE() &
8282
// type guards, but not in array constructors.
83-
return DynamicTypeWithLength{DynamicType{kind, len}};
83+
DynamicTypeWithLength type{DynamicType{kind, len}};
84+
if (auto lenExpr{type.LEN()}) {
85+
type.length = Fold(context,
86+
AsExpr(Extremum<SubscriptInteger>{Ordering::Greater,
87+
Expr<SubscriptInteger>{0}, std::move(*lenExpr)}));
88+
}
89+
return type;
8490
} else {
8591
return DynamicTypeWithLength{DynamicType{category, kind}};
8692
}
@@ -1584,7 +1590,8 @@ class ArrayConstructorContext {
15841590
std::optional<Expr<SubscriptInteger>> LengthIfGood() const {
15851591
if (type_) {
15861592
auto len{type_->LEN()};
1587-
if (len && IsConstantExpr(*len) && !ContainsAnyImpliedDoIndex(*len)) {
1593+
if (explicitType_ ||
1594+
(len && IsConstantExpr(*len) && !ContainsAnyImpliedDoIndex(*len))) {
15881595
return len;
15891596
}
15901597
}
@@ -1939,7 +1946,8 @@ MaybeExpr ArrayConstructorContext::ToExpr() {
19391946

19401947
MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayConstructor &array) {
19411948
const parser::AcSpec &acSpec{array.v};
1942-
ArrayConstructorContext acContext{*this, AnalyzeTypeSpec(acSpec.type)};
1949+
ArrayConstructorContext acContext{
1950+
*this, AnalyzeTypeSpec(acSpec.type, GetFoldingContext())};
19431951
for (const parser::AcValue &value : acSpec.values) {
19441952
acContext.Add(value);
19451953
}

flang/test/Lower/HLFIR/array-ctor-character.f90

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,11 @@ subroutine test_set_length_sanitize(i, c1)
9393
call takes_char([character(len=i):: c1])
9494
end subroutine
9595
! CHECK-LABEL: func.func @_QPtest_set_length_sanitize(
96-
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare {{.*}}Ec1
97-
! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare {{.*}}Ei
98-
! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i64>
96+
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare {{.*}}Ec1
97+
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %arg0
98+
! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i64>
99+
! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i64>
99100
! CHECK: %[[VAL_26:.*]] = arith.constant 0 : i64
100101
! CHECK: %[[VAL_27:.*]] = arith.cmpi sgt, %[[VAL_25]], %[[VAL_26]] : i64
101102
! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i64
102-
! CHECK: %[[VAL_29:.*]] = hlfir.set_length %[[VAL_6]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,?>>
103+
! CHECK: %[[VAL_29:.*]] = hlfir.set_length %[[VAL_2]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,?>>

flang/test/Semantics/array-constr-len.f90

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@ subroutine subr(s,n)
1010
print *, [(s(1:j),j=1,0)]
1111
print *, [(s(1:1),j=1,0)] ! ok
1212
print *, [character(2)::(s(1:n),j=1,0)] ! ok
13-
!ERROR: Array constructor implied DO loop has no iterations and indeterminate character length
1413
print *, [character(n)::(s(1:n),j=1,0)]
1514
end

0 commit comments

Comments
 (0)