[flang-commits] [flang] [flang] lower assumed type actual arguments in call statements (PR #75969)

Anthony Cabrera via flang-commits flang-commits at lists.llvm.org
Tue Dec 19 13:09:04 PST 2023


https://github.com/cabreraam created https://github.com/llvm/llvm-project/pull/75969

Taking care of TODOs for assumed type actual arguments in `CALL` statements.

The approach here borrows from the commits in [this pull request that addresses assumed type actual arguments in intrinsic functions](https://reviews.llvm.org/D147513).

>From dec9ebe26422186612ded6167a5c6761130d3247 Mon Sep 17 00:00:00 2001
From: cabreraam <cabreraam33 at gmail.com>
Date: Tue, 19 Dec 2023 15:51:17 -0500
Subject: [PATCH] [flang] lower assumed type actual arguments in call
 statements

---
 flang/lib/Lower/ConvertCall.cpp               | 23 ++++++++---
 .../HLFIR/assumed-type-actual-arguments.f90   | 39 +++++++++++++++++++
 2 files changed, 57 insertions(+), 5 deletions(-)
 create mode 100644 flang/test/HLFIR/assumed-type-actual-arguments.f90

diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index fd726c90c07bd0..90421d82d7c48d 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -897,7 +897,8 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
   }
 
   // NULL() actual to procedure pointer dummy
-  if (Fortran::evaluate::IsNullProcedurePointer(expr) &&
+  if (arg.entity->UnwrapExpr() /* TYPE(*) dummy */ &&
+      Fortran::evaluate::IsNullProcedurePointer(expr) &&
       hlfir::isBoxProcAddressType(dummyType)) {
     auto boxTy{Fortran::lower::getUntypedBoxProcType(builder.getContext())};
     auto tempBoxProc{builder.createTemporary(loc, boxTy)};
@@ -1172,8 +1173,6 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
       continue;
     }
     const auto *expr = arg.entity->UnwrapExpr();
-    if (!expr)
-      TODO(loc, "assumed type actual argument");
 
     switch (arg.passBy) {
     case PassBy::Value: {
@@ -2207,8 +2206,22 @@ genProcedureRef(CallContext &callContext) {
        caller.getPassedArguments())
     if (const auto *actual = arg.entity) {
       const auto *expr = actual->UnwrapExpr();
-      if (!expr)
-        TODO(loc, "assumed type actual argument");
+      if (!expr) {
+        // TYPE(*) dummy. They are only allowed as argument of a few intrinsics
+        // that do not take optional arguments: see Fortran 2018 standard C710.
+        const Fortran::evaluate::Symbol *assumedTypeSym =
+            actual->GetAssumedTypeDummy();
+        if (!assumedTypeSym)
+          fir::emitFatalError(
+              loc, "expected assumed-type symbol as actual argument");
+        std::optional<fir::FortranVariableOpInterface> var =
+            callContext.symMap.lookupVariableDefinition(*assumedTypeSym);
+        if (!var)
+          fir::emitFatalError(loc, "assumed-type symbol was not lowered");
+        loweredActuals.push_back(Fortran::lower::PreparedActualArgument{
+            hlfir::Entity{*var}, /*isPresent=*/std::nullopt});
+        continue;
+      }
       if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(
               *expr)) {
         if ((arg.passBy !=
diff --git a/flang/test/HLFIR/assumed-type-actual-arguments.f90 b/flang/test/HLFIR/assumed-type-actual-arguments.f90
new file mode 100644
index 00000000000000..716dc2dbb39493
--- /dev/null
+++ b/flang/test/HLFIR/assumed-type-actual-arguments.f90
@@ -0,0 +1,39 @@
+! Test lowering of call statements to HLFIR with assumed types
+! arguments. These are a bit special because semantics do not represent
+! assumed types actual arguments with an evaluate::Expr like for usual
+! arguments.
+! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s
+
+subroutine test1(x)
+  type(*) :: x
+  interface
+    subroutine fun1(x)
+      type(*) :: x
+    end subroutine
+  end interface
+  call fun1(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest1(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<none> {fir.bindc_name = "x"}) {
+! CHECK:   %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFtest1Ex"} : (!fir.ref<none>) -> (!fir.ref<none>, !fir.ref<none>)
+! CHECK:   fir.call @_QPfun1(%[[VAL_0]]#1) fastmath<contract> : (!fir.ref<none>) -> ()
+! CHECK:   return
+! CHECK: }
+
+subroutine test2(x)
+  type(*) :: x
+  interface
+    subroutine fun2(x)
+      type(*) :: x(:)
+    end subroutine
+  end interface
+  call fun2(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest2(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<none> {fir.bindc_name = "x"}) {
+! CHECK:   %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFtest2Ex"} : (!fir.ref<none>) -> (!fir.ref<none>, !fir.ref<none>)
+! CHECK:   %[[VAL_1:.*]] = fir.embox %[[VAL_0]]#0 : (!fir.ref<none>) -> !fir.box<none>
+! CHECK:   %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (!fir.box<none>) -> !fir.box<!fir.array<?xnone>>
+! CHECK:   fir.call @_QPfun2(%[[VAL_2]]) fastmath<contract> : (!fir.box<!fir.array<?xnone>>) -> ()
+! CHECK:   return
+! CHECK: }
\ No newline at end of file



More information about the flang-commits mailing list