Skip to content

Commit ddb36a8

Browse files
authored
[flang] Preserve dynamic length of characters in ALLOCATE (llvm#152564)
Fixes llvm#151895
1 parent 1217c82 commit ddb36a8

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

flang/lib/Lower/Allocatable.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,16 @@ class AllocateStmtHelper {
490490
return;
491491
}
492492

493+
// Preserve characters' dynamic length.
494+
if (lenParams.empty() && box.isCharacter() &&
495+
!box.hasNonDeferredLenParams()) {
496+
auto charTy = mlir::dyn_cast<fir::CharacterType>(box.getEleTy());
497+
if (charTy && charTy.hasDynamicLen()) {
498+
fir::ExtendedValue exv{box};
499+
lenParams.push_back(fir::factory::readCharLen(builder, loc, exv));
500+
}
501+
}
502+
493503
// Generate a sequence of runtime calls.
494504
errorManager.genStatCheck(builder, loc);
495505
genAllocateObjectInit(box, allocatorIdx);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
!RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
2+
3+
!CHECK-LABEL: func @_QPtest_dynlen_char_ptr
4+
!CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %[[A:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>) {
5+
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_dynlen_char_ptrEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>)
6+
!CHECK: %[[A_VAL:.*]] = fir.load %[[A_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>
7+
!CHECK: %[[LEN:.*]] = fir.box_elesize %[[A_VAL]] : (!fir.box<!fir.ptr<!fir.char<1,?>>>) -> index
8+
!CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A_DECL]]#0 : (!fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>) -> !fir.ref<!fir.box<none>>
9+
!CHECK: %[[LEN_I64:.*]] = fir.convert %[[LEN]] : (index) -> i64
10+
!CHECK: fir.call @_FortranAPointerNullifyCharacter(%[[A_BOX_NONE]], %[[LEN_I64]], {{.*}})
11+
subroutine test_dynlen_char_ptr(i)
12+
character(i), pointer :: a
13+
14+
!$omp parallel private(a)
15+
allocate(a)
16+
a = "abc"
17+
!$omp end parallel
18+
end subroutine
19+
20+
!CHECK-LABEL: func @_QPtest_dynlen_char_ptr_array
21+
!CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %[[A:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>) {
22+
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_dynlen_char_ptr_arrayEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>)
23+
!CHECK: %[[A_VAL:.*]] = fir.load %[[A_DECL]]#0
24+
!CHECK: %[[LEN:.*]] = fir.box_elesize %[[A_VAL]]
25+
!CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A_DECL]]#0 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>) -> !fir.ref<!fir.box<none>>
26+
!CHECK: %[[LEN_I64:.*]] = fir.convert %[[LEN]] : (index) -> i64
27+
!CHECK: fir.call @_FortranAPointerNullifyCharacter(%[[A_BOX_NONE]], %[[LEN_I64]], {{.*}})
28+
subroutine test_dynlen_char_ptr_array(i)
29+
character(i), pointer :: a(:)
30+
31+
!$omp parallel private(a)
32+
allocate(a(i))
33+
a = "abc"
34+
!$omp end parallel
35+
end subroutine

0 commit comments

Comments
 (0)