diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 90900d9acb6ad..2d91962a24a4c 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -63,7 +63,7 @@ std::optional> DynamicTypeWithLength::LEN() const { } static std::optional AnalyzeTypeSpec( - const std::optional &spec) { + const std::optional &spec, FoldingContext &context) { if (spec) { if (const semantics::DeclTypeSpec *typeSpec{spec->declTypeSpec}) { // Name resolution sets TypeSpec::declTypeSpec only when it's valid @@ -80,7 +80,13 @@ static std::optional 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{Ordering::Greater, + Expr{0}, std::move(*lenExpr)})); + } + return type; } else { return DynamicTypeWithLength{DynamicType{category, kind}}; } @@ -1584,7 +1590,8 @@ class ArrayConstructorContext { std::optional> LengthIfGood() const { if (type_) { auto len{type_->LEN()}; - if (len && IsConstantExpr(*len) && !ContainsAnyImpliedDoIndex(*len)) { + if (explicitType_ || + (len && IsConstantExpr(*len) && !ContainsAnyImpliedDoIndex(*len))) { return len; } } @@ -1939,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); } diff --git a/flang/test/Lower/HLFIR/array-ctor-character.f90 b/flang/test/Lower/HLFIR/array-ctor-character.f90 index 85e6ed27fe077..881085b370ffe 100644 --- a/flang/test/Lower/HLFIR/array-ctor-character.f90 +++ b/flang/test/Lower/HLFIR/array-ctor-character.f90 @@ -93,10 +93,11 @@ subroutine test_set_length_sanitize(i, c1) call takes_char([character(len=i):: c1]) end subroutine ! CHECK-LABEL: func.func @_QPtest_set_length_sanitize( -! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare {{.*}}Ec1 -! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare {{.*}}Ei -! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare {{.*}}Ec1 +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %arg0 +! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref +! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref ! CHECK: %[[VAL_26:.*]] = arith.constant 0 : i64 ! CHECK: %[[VAL_27:.*]] = arith.cmpi sgt, %[[VAL_25]], %[[VAL_26]] : i64 ! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i64 -! CHECK: %[[VAL_29:.*]] = hlfir.set_length %[[VAL_6]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr> +! CHECK: %[[VAL_29:.*]] = hlfir.set_length %[[VAL_2]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr> diff --git a/flang/test/Semantics/array-constr-len.f90 b/flang/test/Semantics/array-constr-len.f90 index a785c9e2ece6d..4de9c76c7041c 100644 --- a/flang/test/Semantics/array-constr-len.f90 +++ b/flang/test/Semantics/array-constr-len.f90 @@ -10,6 +10,5 @@ subroutine subr(s,n) print *, [(s(1:j),j=1,0)] print *, [(s(1:1),j=1,0)] ! ok print *, [character(2)::(s(1:n),j=1,0)] ! ok - !ERROR: Array constructor implied DO loop has no iterations and indeterminate character length print *, [character(n)::(s(1:n),j=1,0)] end