Skip to content

Commit d07f23e

Browse files
committed
[flang][hlfir] Use actual type when copying an actual argument variable
The copy must made according to the actual type, not the dummy type. In case the dummy is polymorphic, these types will be different and the dynamic type of the copy passed in the call should be the one of the actual. There is no support for "class(t), value" yet (it is hitting a TODO in CallInterface that is moot for HLFIR but has not been lifted for lack of proper testing) so the bug was dormant, but D151271 created a situation where a copy is needed with polymorphic dummies and exposed the bug. This led to a compile time assert "value.isScalar() && fir::isa_trivial(value.getType())" in "hlfir::genAssociateExpr". Differential Revision: https://reviews.llvm.org/D151413
1 parent 2912234 commit d07f23e

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

flang/lib/Lower/ConvertCall.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,9 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
921921
entity.isParameter()) {
922922
// Make a copy in a temporary.
923923
auto copy = builder.create<hlfir::AsExprOp>(loc, entity);
924+
mlir::Type storageType = entity.getType();
924925
hlfir::AssociateOp associate = hlfir::genAssociateExpr(
925-
loc, builder, hlfir::Entity{copy}, dummyType, "adapt.valuebyref");
926+
loc, builder, hlfir::Entity{copy}, storageType, "adapt.valuebyref");
926927
entity = hlfir::Entity{associate.getBase()};
927928
// Register the temporary destruction after the call.
928929
preparedDummy.setExprAssociateCleanUp(
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
! RUN: bbc -emit-fir -hlfir --polymorphic-type -o - %s | FileCheck %s
2+
3+
! Test when constant argument are copied in memory
4+
! and passed to polymorphic arguments.
5+
! The copy is done in case the dummy later appear in a
6+
! copy-out that would create write to this memory location.
7+
type t1
8+
integer :: i
9+
end type
10+
type, extends(t1) :: t2
11+
integer :: j
12+
end type
13+
interface
14+
subroutine foo(x)
15+
import :: t1
16+
class(t1) :: x(:)
17+
end subroutine
18+
end interface
19+
20+
call foo([t2(0,0)])
21+
end
22+
! CHECK-LABEL: func.func @_QQmain() {
23+
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}}(%[[VAL_2:.*]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.1x_QFTt2.0"}
24+
! CHECK: %[[VAL_4:.*]] = hlfir.as_expr %[[VAL_3]]#0 : (!fir.ref<!fir.array<1x!fir.type<_QFTt2{i:i32,j:i32}>>>) -> !hlfir.expr<1x!fir.type<_QFTt2{i:i32,j:i32}>>
25+
! CHECK: %[[VAL_5:.*]]:3 = hlfir.associate %[[VAL_4]](%[[VAL_2]]) {uniq_name = "adapt.valuebyref"} : (!hlfir.expr<1x!fir.type<_QFTt2{i:i32,j:i32}>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1x!fir.type<_QFTt2{i:i32,j:i32}>>>, !fir.ref<!fir.array<1x!fir.type<_QFTt2{i:i32,j:i32}>>>, i1)
26+
! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]]#0(%[[VAL_2]]) : (!fir.ref<!fir.array<1x!fir.type<_QFTt2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<1x!fir.type<_QFTt2{i:i32,j:i32}>>>
27+
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.array<1x!fir.type<_QFTt2{i:i32,j:i32}>>>) -> !fir.class<!fir.array<?x!fir.type<_QFTt1{i:i32}>>>
28+
! CHECK: fir.call @_QPfoo(%[[VAL_7]]) {{.*}}: (!fir.class<!fir.array<?x!fir.type<_QFTt1{i:i32}>>>) -> ()
29+
! CHECK: hlfir.end_associate %[[VAL_5]]#1, %[[VAL_5]]#2 : !fir.ref<!fir.array<1x!fir.type<_QFTt2{i:i32,j:i32}>>>, i1

0 commit comments

Comments
 (0)