diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp index 0b1e57e8f6c37..17efa45b8667d 100644 --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -1132,8 +1132,13 @@ hlfir::genTypeAndKindConvert(mlir::Location loc, fir::FirOpBuilder &builder, std::optional toKindCharConvert; if (auto toCharTy = mlir::dyn_cast(toType)) { if (auto fromCharTy = mlir::dyn_cast(fromType)) - if (toCharTy.getFKind() != fromCharTy.getFKind()) + if (toCharTy.getFKind() != fromCharTy.getFKind()) { toKindCharConvert = toCharTy.getFKind(); + // Preserve source length (padding/truncation will occur in assignment + // if needed). + toType = fir::CharacterType::get( + fromType.getContext(), toCharTy.getFKind(), fromCharTy.getLen()); + } // Do not convert in case of character length mismatch only, hlfir.assign // deals with it. if (!toKindCharConvert) diff --git a/flang/test/Lower/HLFIR/implicit-type-conversion-allocatable.f90 b/flang/test/Lower/HLFIR/implicit-type-conversion-allocatable.f90 index 7083a825dfd3b..361cd61adea2d 100644 --- a/flang/test/Lower/HLFIR/implicit-type-conversion-allocatable.f90 +++ b/flang/test/Lower/HLFIR/implicit-type-conversion-allocatable.f90 @@ -38,3 +38,29 @@ subroutine preserve_lbounds(x, y) ! CHECK: hlfir.destroy %[[VAL_8]] : !hlfir.expr ! CHECK: return ! CHECK: } + +! Test that RHS character length is preserved in a character KIND +! conversion before the assignment. +subroutine kind_and_length(a, b) + character(len=4,kind=4), allocatable :: a(:) + character(len=2,kind=1) :: b(:) + a = b +end subroutine +! CHECK-LABEL: func.func @_QPkind_and_length( +! CHECK: %[[VAL_2:.*]] = arith.constant 4 : index +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]] typeparams %[[VAL_2:[a-z0-9]*]] {{.*}}Ea +! CHECK: %[[VAL_4:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_1:[a-z0-9]*]] typeparams %[[VAL_4:[a-z0-9]*]] {{.*}}Eb +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_5]]#0, %[[VAL_6]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_8]] typeparams %[[VAL_4]] unordered : (!fir.shape<1>, index) -> !hlfir.expr> { +! CHECK: ^bb0(%[[VAL_10:.*]]: index): +! CHECK: %[[VAL_11:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_10]]) typeparams %[[VAL_4]] : (!fir.box>>, index, index) -> !fir.ref> +! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.char<4,?>(%[[VAL_4]] : index) +! CHECK: fir.char_convert %[[VAL_11]] for %[[VAL_4]] to %[[VAL_12]] : !fir.ref>, index, !fir.ref> +! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_12:[a-z0-9]*]] typeparams %[[VAL_4:[a-z0-9]*]] {uniq_name = ".temp.kindconvert"} : (!fir.ref>, index) -> (!fir.boxchar<4>, !fir.ref>) +! CHECK: hlfir.yield_element %[[VAL_13]]#0 : !fir.boxchar<4> +! CHECK: } +! CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_3]]#0 realloc keep_lhs_len : !hlfir.expr>, !fir.ref>>>> +