diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -433,11 +433,22 @@ // Do not use dynamic type length here. We would miss constant // lengths opportunities because dynamic type only has the length // if it comes from a declaration. - auto charExpr = - std::get>( - expr.u); - if (auto constantLen = toInt64(charExpr.LEN())) - return *constantLen; + if (const auto *charExpr = std::get_if< + Fortran::evaluate::Expr>( + &expr.u)) { + if (auto constantLen = toInt64(charExpr->LEN())) + return *constantLen; + } else if (auto dynamicType = expr.GetType()) { + // When generating derived type type descriptor as structure constructor, + // semantics wraps designators to data component initialization into + // CLASS(*), regardless of their actual type. + // GetType() will recover the actual symbol type as the dynamic type, so + // getCharacterLength may be reached even if expr is packaged as an + // Expr instead of an Expr. + // Just use the dynamic type here again to retrieve the length. + if (auto constantLen = toInt64(dynamicType->GetCharLength())) + return *constantLen; + } return fir::SequenceType::getUnknownExtent(); } diff --git a/flang/test/Lower/HLFIR/tdesc-character-comp-init.f90 b/flang/test/Lower/HLFIR/tdesc-character-comp-init.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/HLFIR/tdesc-character-comp-init.f90 @@ -0,0 +1,13 @@ +! Test lowering of derived type descriptor for types with +! a default initialized character component. + +! RUN: bbc -emit-fir -hlfir -o - %s | FileCheck %s + +subroutine test() + type t + character(5) :: character_comp = "hello" + end type + type(t) :: x +end subroutine +! CHECK-LABEL: fir.global {{.*}} @_QFtestE.c.t constant +! CHECK: fir.address_of(@_QFtestE.di.t.character_comp) : !fir.ref>