|
11 | 11 | //===----------------------------------------------------------------------===// |
12 | 12 |
|
13 | 13 | #include "flang/Lower/ConvertCall.h" |
| 14 | +#include "flang/Lower/Allocatable.h" |
14 | 15 | #include "flang/Lower/ConvertExprToHLFIR.h" |
15 | 16 | #include "flang/Lower/ConvertVariable.h" |
16 | 17 | #include "flang/Lower/CustomIntrinsicCall.h" |
@@ -1199,12 +1200,21 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals, |
1199 | 1200 | } |
1200 | 1201 | // Passing a POINTER to a POINTER, or an ALLOCATABLE to an ALLOCATABLE. |
1201 | 1202 | assert(actual.isMutableBox() && "actual must be a mutable box"); |
1202 | | - caller.placeInput(arg, actual); |
1203 | 1203 | if (fir::isAllocatableType(argTy) && arg.isIntentOut() && |
1204 | 1204 | Fortran::semantics::IsBindCProcedure( |
1205 | 1205 | *callContext.procRef.proc().GetSymbol())) { |
1206 | | - TODO(loc, "BIND(C) INTENT(OUT) allocatable deallocation in HLFIR"); |
| 1206 | + // INTENT(OUT) allocatables are deallocated on the callee side, |
| 1207 | + // but BIND(C) procedures may be implemented in C, so deallocation is |
| 1208 | + // also done on the caller side (if the procedure is implemented in |
| 1209 | + // Fortran, the deallocation attempt in the callee will be a no-op). |
| 1210 | + auto [exv, cleanup] = |
| 1211 | + hlfir::translateToExtendedValue(loc, builder, actual); |
| 1212 | + const auto *mutableBox = exv.getBoxOf<fir::MutableBoxValue>(); |
| 1213 | + assert(mutableBox && !cleanup && "expect allocatable"); |
| 1214 | + Fortran::lower::genDeallocateIfAllocated(callContext.converter, |
| 1215 | + *mutableBox, loc); |
1207 | 1216 | } |
| 1217 | + caller.placeInput(arg, actual); |
1208 | 1218 | } break; |
1209 | 1219 | } |
1210 | 1220 | } |
|
0 commit comments