[flang][hlfir] Fixed character allocatable in structure constructor.
authorSlava Zakharin <szakharin@nvidia.com>
Thu, 13 Jul 2023 16:44:39 +0000 (09:44 -0700)
committerSlava Zakharin <szakharin@nvidia.com>
Thu, 13 Jul 2023 16:44:39 +0000 (09:44 -0700)
commit1fa4a0a012511643868b3ab9a4659aa6eae696ca
tree2f76d6bfebd36af4e1bb399a5f895835eabc34d6
parentd986462b50536082065a44d12eeed1d0e1539976
[flang][hlfir] Fixed character allocatable in structure constructor.

The problem appeared as a segfault for case like this:
```
type t
character(11), allocatable :: c
end type
character(12), alloctable :: x
type(t) y
y = t(x)
```

The frontend representes `y = t(x)` as `y=t(c=%SET_LENGTH(x,11_8))`.
When 'x' is unallocated the hlfir.set_length lowering results in
segfault. It could probably be handled in hlfir.set_length lowering
by using NULL base for the hlfir.declare depending on the allocation
status of 'x', but I am not sure if !hlfir.expr, in general, is supposed
to represent an expression created from unallocated allocatable.
I believe in Fortran that would mean referencing an unallocated
allocatable, which is not allowed.

I decided to special case `SET_LENGTH` in structure constructor,
so that we use its 'x' operand as the RHS for the assign operation
implying the isAllocatable check for cases when 'x' is allocatable.
This requires setting keep_lhs_length_if_realloc flag for the assign
operation. Note that when the component being intialized has
deferred length the frontend does not produce `SET_LENGTH`.

Differential Revision: https://reviews.llvm.org/D155151
flang/include/flang/Optimizer/HLFIR/HLFIROps.td
flang/lib/Lower/ConvertExprToHLFIR.cpp
flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
flang/test/HLFIR/invalid.fir
flang/test/Lower/HLFIR/structure-constructor.f90