Skip to content

Commit 8252137

Browse files
authored
[flang] Lower struct ctor with character allocatable components (#79179)
There is no need to gather the length parameters from the parameter symbols when facing a deferred length allocatable components in a structure constructor, the length is set as part of the assignment given the value. Remove the checks for derived type runtime info symbols, this is not relevant for what is being tested here.
1 parent e5e1a89 commit 8252137

File tree

2 files changed

+70
-66
lines changed

2 files changed

+70
-66
lines changed

flang/lib/Lower/ConvertExprToHLFIR.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,14 @@ struct UnaryOp<
13831383
}
13841384
};
13851385

1386+
static bool hasDeferredCharacterLength(const Fortran::semantics::Symbol &sym) {
1387+
const Fortran::semantics::DeclTypeSpec *type = sym.GetType();
1388+
return type &&
1389+
type->category() ==
1390+
Fortran::semantics::DeclTypeSpec::Category::Character &&
1391+
type->characterTypeSpec().length().isDeferred();
1392+
}
1393+
13861394
/// Lower Expr to HLFIR.
13871395
class HlfirBuilder {
13881396
public:
@@ -1719,8 +1727,12 @@ class HlfirBuilder {
17191727
mlir::Type idxType = builder.getIndexType();
17201728
typeParams.push_back(
17211729
builder.createIntegerConstant(loc, idxType, charType.getLen()));
1722-
} else {
1723-
TODO(loc, "dynamic character length in structure constructor");
1730+
} else if (!hasDeferredCharacterLength(sym)) {
1731+
// If the length is not deferred, this is a parametrized derived type
1732+
// where the character length depends on the derived type length
1733+
// parameters. Otherwise, this is a pointer/allocatable component and
1734+
// the length will be set during the assignment.
1735+
TODO(loc, "automatic character component in structure constructor");
17241736
}
17251737
}
17261738

flang/test/Lower/structure-constructors-alloc-comp.f90

Lines changed: 56 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,27 @@
33

44
module m_struct_ctor
55
implicit none
6+
67
type t_alloc
78
real :: x
89
integer, allocatable :: a(:)
910
end type
1011

12+
type t_alloc_char
13+
character(:), allocatable :: a
14+
end type
15+
16+
type t_alloc_char_cst_len
17+
character(2), allocatable :: a
18+
end type
19+
1120
contains
1221
subroutine test_alloc1(y)
1322
real :: y
1423
call print_alloc_comp(t_alloc(x=y, a=null()))
1524
! HLFIR-LABEL: func.func @_QMm_struct_ctorPtest_alloc1(
1625
! HLFIR-SAME: %[[ARG_0:.*]]: !fir.ref<f32> {fir.bindc_name = "y"}) {
1726
! HLFIR: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
18-
! HLFIR: %[[VAL_1:.*]] = fir.address_of(@_QMm_struct_ctorE.n.x) : !fir.ref<!fir.char<1>>
19-
! HLFIR: %[[CONS_1:.*]] = arith.constant 1 : index
20-
! HLFIR: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {{.*}}"_QMm_struct_ctorE.n.x"
21-
! HLFIR: %[[VAL_3:.*]] = fir.address_of(@_QMm_struct_ctorE.n.a) : !fir.ref<!fir.char<1>>
22-
! HLFIR: %[[CONS_2:.* ]]= arith.constant 1 : index
23-
! HLFIR: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {{.*}}"_QMm_struct_ctorE.n.a"
24-
! HLFIR: %[[VAL_5:.*]] = fir.address_of(@_QMm_struct_ctorE.n.t_alloc) : !fir.ref<!fir.char<1,7>>
25-
! HLFIR: %[[CONS_3:.*]] = arith.constant 7 : index
26-
! HLFIR: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {{.*}}"_QMm_struct_ctorE.n.t_alloc"
27-
! HLFIR: %[[VAL_7:.*]] = fir.address_of(@_QMm_struct_ctorE.c.t_alloc)
28-
! HLFIR: %[[CONS_4:.*]] = arith.constant 0 : index
29-
! HLFIR: %[[CONS_5:.*]] = arith.constant 2 : index
30-
! HLFIR: %[[VAL_8:.*]] = fir.shape_shift %[[CONS_4]], %[[CONS_5]] : (index, index) -> !fir.shapeshift<1>
31-
! HLFIR: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) {{.*}}"_QMm_struct_ctorE.c.t_alloc"
32-
! HLFIR: %[[VAL_10:.*]] = fir.address_of(@_QMm_struct_ctorE.dt.t_alloc)
33-
! HLFIR: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {{.*}}"_QMm_struct_ctorE.dt.t_alloc"
3427
! HLFIR: %[[VAL_12:.*]]:2 = hlfir.declare %[[ARG_0]] {uniq_name = "_QMm_struct_ctorFtest_alloc1Ey"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
3528
! HLFIR: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
3629
! HLFIR: %[[VAL_14:.*]] = fir.embox %[[VAL_13]]#0 : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
@@ -54,22 +47,6 @@ subroutine test_alloc2(y, b)
5447
! HLFIR-LABEL: func.func @_QMm_struct_ctorPtest_alloc2
5548
! HLFIR-SAME: (%[[ARG_0:.*]]: !fir.ref<f32> {fir.bindc_name = "y"}, %[[ARG_1:.*]]: !fir.ref<!fir.array<5xi32>> {fir.bindc_name = "b"}) {
5649
! HLFIR: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
57-
! HLFIR: %[[VAL_1:.*]] = fir.address_of(@_QMm_struct_ctorE.n.x) : !fir.ref<!fir.char<1>>
58-
! HLFIR: %[[CONS_1:.*]] = arith.constant 1 : index
59-
! HLFIR: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] typeparams %[[CONS_1]] {{.*}}"_QMm_struct_ctorE.n.x"
60-
! HLFIR: %[[VAL_3:.*]] = fir.address_of(@_QMm_struct_ctorE.n.a) : !fir.ref<!fir.char<1>>
61-
! HLFIR: %[[CONS_2:.*]] = arith.constant 1 : index
62-
! HLFIR: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] typeparams %[[CONS_2]] {{.*}}"_QMm_struct_ctorE.n.a"
63-
! HLFIR: %[[VAL_5:.*]] = fir.address_of(@_QMm_struct_ctorE.n.t_alloc) : !fir.ref<!fir.char<1,7>>
64-
! HLFIR: %[[CONS_3:.*]] = arith.constant 7 : index
65-
! HLFIR: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[CONS_3]] {{.*}}"_QMm_struct_ctorE.n.t_alloc"
66-
! HLFIR: %[[VAL_7:.*]] = fir.address_of(@_QMm_struct_ctorE.c.t_alloc)
67-
! HLFIR: %[[CONS_4:.*]] = arith.constant 0 : index
68-
! HLFIR: %[[CONS_5:.*]] = arith.constant 2 : index
69-
! HLFIR: %[[VAL_8:.*]] = fir.shape_shift %[[CONS_4]], %[[CONS_5]] : (index, index) -> !fir.shapeshift<1>
70-
! HLFIR: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) {{.*}}"_QMm_struct_ctorE.c.t_alloc"
71-
! HLFIR: %[[VAL_10:.*]] = fir.address_of(@_QMm_struct_ctorE.dt.t_alloc)
72-
! HLFIR: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {{.*}}"_QMm_struct_ctorE.dt.t_alloc"
7350
! HLFIR: %[[CONS_6:.*]] = arith.constant 5 : index
7451
! HLFIR: %[[VAL_12:.*]] = fir.shape %[[CONS_6]] : (index) -> !fir.shape<1>
7552
! HLFIR: %[[VAL_13:.*]]:2 = hlfir.declare %[[ARG_1]](%[[VAL_12]]) {uniq_name = "_QMm_struct_ctorFtest_alloc2Eb"} : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.array<5xi32>>)
@@ -94,22 +71,6 @@ subroutine test_alloc2(y, b)
9471
subroutine test_alloc3()
9572
type(t_alloc) :: t1 = t_alloc(x=5, a=null())
9673
! HLFIR-LABEL: func.func @_QMm_struct_ctorPtest_alloc3() {
97-
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@_QMm_struct_ctorE.n.x) : !fir.ref<!fir.char<1>>
98-
! HLFIR: %c1 = arith.constant 1 : index
99-
! HLFIR: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %c1 {{.*}}"_QMm_struct_ctorE.n.x"
100-
! HLFIR: %[[VAL_2:.*]] = fir.address_of(@_QMm_struct_ctorE.n.a) : !fir.ref<!fir.char<1>>
101-
! HLFIR: %c1_0 = arith.constant 1 : index
102-
! HLFIR: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %c1_0 {{.*}}"_QMm_struct_ctorE.n.a"
103-
! HLFIR: %[[VAL_4:.*]] = fir.address_of(@_QMm_struct_ctorE.n.t_alloc) : !fir.ref<!fir.char<1,7>>
104-
! HLFIR: %c7 = arith.constant 7 : index
105-
! HLFIR: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] typeparams %c7 {{.*}}"_QMm_struct_ctorE.n.t_alloc"
106-
! HLFIR: %[[VAL_6:.*]] = fir.address_of(@_QMm_struct_ctorE.c.t_alloc)
107-
! HLFIR: %c0 = arith.constant 0 : index
108-
! HLFIR: %c2 = arith.constant 2 : index
109-
! HLFIR: %[[VAL_7:.*]] = fir.shape_shift %c0, %c2 : (index, index) -> !fir.shapeshift<1>
110-
! HLFIR: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_6]](%[[VAL_7]]) {{.*}}"_QMm_struct_ctorE.c.t_alloc"
111-
! HLFIR: %[[VAL_9:.*]] = fir.address_of(@_QMm_struct_ctorE.dt.t_alloc)
112-
! HLFIR: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] {{.*}}"_QMm_struct_ctorE.dt.t_alloc"
11374
! HLFIR: %[[VAL_11:.*]] = fir.address_of(@_QMm_struct_ctorFtest_alloc3Et1) : !fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
11475
! HLFIR: {{.*}}:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QMm_struct_ctorFtest_alloc3Et1"}
11576
! HLFIR: return
@@ -120,22 +81,6 @@ subroutine test_alloc4()
12081
integer, pointer :: p(:)
12182
type(t_alloc) :: t1 = t_alloc(x=5, a=null(p))
12283
! HLFIR-LABEL: func.func @_QMm_struct_ctorPtest_alloc4() {
123-
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@_QMm_struct_ctorE.n.x) : !fir.ref<!fir.char<1>>
124-
! HLFIR: %[[CONS_1:.*]] = arith.constant 1 : index
125-
! HLFIR: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[CONS_1]] {{.*}}"_QMm_struct_ctorE.n.x"
126-
! HLFIR: %[[VAL_2:.*]] = fir.address_of(@_QMm_struct_ctorE.n.a) : !fir.ref<!fir.char<1>>
127-
! HLFIR: %[[CONS_2:.*]] = arith.constant 1 : index
128-
! HLFIR: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[CONS_2]] {{.*}}"_QMm_struct_ctorE.n.a"
129-
! HLFIR: %[[VAL_4:.*]] = fir.address_of(@_QMm_struct_ctorE.n.t_alloc) : !fir.ref<!fir.char<1,7>>
130-
! HLFIR: %[[CONS_3:.*]] = arith.constant 7 : index
131-
! HLFIR: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] typeparams %[[CONS_3]] {{.*}}"_QMm_struct_ctorE.n.t_alloc"
132-
! HLFIR: %[[VAL_6:.*]] = fir.address_of(@_QMm_struct_ctorE.c.t_alloc)
133-
! HLFIR: %[[CONS_4:.*]] = arith.constant 0 : index
134-
! HLFIR: %[[CONS_5:.*]] = arith.constant 2 : index
135-
! HLFIR: %[[VAL_7:.*]] = fir.shape_shift %[[CONS_4]], %[[CONS_5]] : (index, index) -> !fir.shapeshift<1>
136-
! HLFIR: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_6]](%[[VAL_7]]) {{.*}}"_QMm_struct_ctorE.c.t_alloc"
137-
! HLFIR: %[[VAL_9:.*]] = fir.address_of(@_QMm_struct_ctorE.dt.t_alloc)
138-
! HLFIR: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] {{.*}}"_QMm_struct_ctorE.dt.t_alloc"
13984
! HLFIR: %[[VAL_11:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>> {bindc_name = "p", uniq_name = "_QMm_struct_ctorFtest_alloc4Ep"}
14085
! HLFIR: %[[VAL_12:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
14186
! HLFIR: %[[CONS_6:.*]] = arith.constant 0 : index
@@ -150,3 +95,50 @@ subroutine test_alloc4()
15095
end subroutine
15196

15297
end module m_struct_ctor
98+
99+
subroutine test_character_1()
100+
use m_struct_ctor, only : t_alloc_char
101+
interface
102+
subroutine takes_ta_alloc_char(x)
103+
import t_alloc_char
104+
type(t_alloc_char) :: x
105+
end subroutine
106+
end interface
107+
call takes_ta_alloc_char(t_alloc_char("hello"))
108+
end subroutine
109+
! HLFIR-LABEL: func.func @_QPtest_character_1() {
110+
! HLFIR: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>
111+
! HLFIR: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>) -> (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>, !fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>)
112+
! HLFIR: %[[VAL_2:.*]] = fir.embox %[[VAL_1]]#0 : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>) -> !fir.box<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>
113+
! HLFIR: %[[VAL_5:.*]] = fir.convert %[[VAL_2]] : (!fir.box<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>) -> !fir.box<none>
114+
! HLFIR: %[[VAL_7:.*]] = fir.call @_FortranAInitialize(%[[VAL_5]],
115+
! HLFIR: %[[VAL_8:.*]] = hlfir.designate %[[VAL_1]]#0{"a"} {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
116+
! HLFIR: %[[VAL_9:.*]] = fir.address_of(@_QQclX68656C6C6F) : !fir.ref<!fir.char<1,5>>
117+
! HLFIR: %[[VAL_10:.*]] = arith.constant 5 : index
118+
! HLFIR: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]] typeparams %[[VAL_10]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX68656C6C6F"} : (!fir.ref<!fir.char<1,5>>, index) -> (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,5>>)
119+
! HLFIR: hlfir.assign %[[VAL_11]]#0 to %[[VAL_8]] realloc temporary_lhs : !fir.ref<!fir.char<1,5>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
120+
! HLFIR: fir.call @_QPtakes_ta_alloc_char(%[[VAL_1]]#1) fastmath<contract> : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char{a:!fir.box<!fir.heap<!fir.char<1,?>>>}>>) -> ()
121+
122+
subroutine test_character_2()
123+
use m_struct_ctor, only : t_alloc_char_cst_len
124+
interface
125+
subroutine takes_ta_alloc_char_cst_len(x)
126+
import t_alloc_char_cst_len
127+
type(t_alloc_char_cst_len) :: x
128+
end subroutine
129+
end interface
130+
call takes_ta_alloc_char_cst_len(t_alloc_char_cst_len("hello"))
131+
end subroutine
132+
! HLFIR-LABEL: func.func @_QPtest_character_2() {
133+
! HLFIR: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>
134+
! HLFIR: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>) -> (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>, !fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>)
135+
! HLFIR: %[[VAL_2:.*]] = fir.embox %[[VAL_1]]#0 : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>) -> !fir.box<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>
136+
! HLFIR: %[[VAL_5:.*]] = fir.convert %[[VAL_2]] : (!fir.box<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>) -> !fir.box<none>
137+
! HLFIR: %[[VAL_7:.*]] = fir.call @_FortranAInitialize(%[[VAL_5]],
138+
! HLFIR: %[[VAL_8:.*]] = arith.constant 2 : index
139+
! HLFIR: %[[VAL_9:.*]] = hlfir.designate %[[VAL_1]]#0{"a"} typeparams %[[VAL_8]] {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.char<1,2>>>>
140+
! HLFIR: %[[VAL_10:.*]] = fir.address_of(@_QQclX68656C6C6F) : !fir.ref<!fir.char<1,5>>
141+
! HLFIR: %[[VAL_11:.*]] = arith.constant 5 : index
142+
! HLFIR: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] typeparams %[[VAL_11]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX68656C6C6F"} : (!fir.ref<!fir.char<1,5>>, index) -> (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,5>>)
143+
! HLFIR: hlfir.assign %[[VAL_12]]#0 to %[[VAL_9]] realloc keep_lhs_len temporary_lhs : !fir.ref<!fir.char<1,5>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,2>>>>
144+
! HLFIR: fir.call @_QPtakes_ta_alloc_char_cst_len(%[[VAL_1]]#1) fastmath<contract> : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc_char_cst_len{a:!fir.box<!fir.heap<!fir.char<1,2>>>}>>) -> ()

0 commit comments

Comments
 (0)