[flang-commits] [flang] [flang] Fixed regression in copy-in/copy-out (PR #161259)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Tue Sep 30 03:10:39 PDT 2025


https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/161259

>From 632ed7be408faa9fba2e0db112fa1002c2f351b0 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 29 Sep 2025 13:55:05 -0400
Subject: [PATCH] [flang] Fixed regression in copy-in/copy-out

Removed incorrect polymprphic check, added regression test.

Fixes #159149
---
 flang/lib/Evaluate/check-expression.cpp | 33 -------------------------
 flang/test/Lower/force-temp.f90         | 24 ++++++++++++++++++
 2 files changed, 24 insertions(+), 33 deletions(-)

diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 8931cbe485ac2..af3554c78b3ad 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -1493,36 +1493,6 @@ class CopyInOutExplicitInterface {
     return !actualTreatAsContiguous && dummyNeedsContiguity;
   }
 
-  // Returns true, if actual and dummy have polymorphic differences
-  bool HavePolymorphicDifferences() const {
-    bool dummyIsAssumedRank{dummyObj_.type.attrs().test(
-        characteristics::TypeAndShape::Attr::AssumedRank)};
-    bool actualIsAssumedRank{semantics::IsAssumedRank(actual_)};
-    bool dummyIsAssumedShape{dummyObj_.type.attrs().test(
-        characteristics::TypeAndShape::Attr::AssumedShape)};
-    bool actualIsAssumedShape{semantics::IsAssumedShape(actual_)};
-    if ((actualIsAssumedRank && dummyIsAssumedRank) ||
-        (actualIsAssumedShape && dummyIsAssumedShape)) {
-      // Assumed-rank and assumed-shape arrays are represented by descriptors,
-      // so don't need to do polymorphic check.
-    } else if (!dummyObj_.ignoreTKR.test(common::IgnoreTKR::Type)) {
-      // flang supports limited cases of passing polymorphic to non-polimorphic.
-      // These cases require temporary of non-polymorphic type. (For example,
-      // the actual argument could be polymorphic array of child type,
-      // while the dummy argument could be non-polymorphic array of parent
-      // type.)
-      bool dummyIsPolymorphic{dummyObj_.type.type().IsPolymorphic()};
-      auto actualType{
-          characteristics::TypeAndShape::Characterize(actual_, fc_)};
-      bool actualIsPolymorphic{
-          actualType && actualType->type().IsPolymorphic()};
-      if (actualIsPolymorphic && !dummyIsPolymorphic) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   bool HaveArrayOrAssumedRankArgs() const {
     bool dummyTreatAsArray{dummyObj_.ignoreTKR.test(common::IgnoreTKR::Rank)};
     return IsArrayOrAssumedRank(actual_) &&
@@ -1611,9 +1581,6 @@ bool MayNeedCopy(const ActualArgument *actual,
     if (check.HaveContiguityDifferences()) {
       return true;
     }
-    if (check.HavePolymorphicDifferences()) {
-      return true;
-    }
   } else { // Implicit interface
     if (ExtractCoarrayRef(*actual)) {
       // Coindexed actual args may need copy-in and copy-out with implicit
diff --git a/flang/test/Lower/force-temp.f90 b/flang/test/Lower/force-temp.f90
index d9ba543d46313..5a5e7d0abec5e 100644
--- a/flang/test/Lower/force-temp.f90
+++ b/flang/test/Lower/force-temp.f90
@@ -27,6 +27,14 @@ subroutine pass_intent_out(buf)
       integer, intent(out) :: buf(5)
     end subroutine
   end interface
+
+  ! Used by s6() and call_s6()
+  type base
+    integer :: i = -1
+  end type
+  type, extends (base) :: child
+    real :: r = -2.0
+  end type
 contains
   subroutine s1(buf)
 !CHECK-LABEL: func.func @_QMtestPs1
@@ -79,4 +87,20 @@ subroutine s5()
     p => x(::2) ! pointer to non-contiguous array section
     call pass_intent_out(p)
   end subroutine
+  subroutine call_s6()
+!CHECK-LABEL: func.func @_QMtestPcall_s6
+!CHECK-NOT: hlfir.copy_in
+!CHECK: fir.call @_QMtestPs6
+!CHECK-NOT: hlfir.copy_out
+    class(base), pointer :: pb(:)
+    type(child), target :: c(2)
+
+    c = (/(child (i, real(i*2)), i=1,size(c))/)
+    pb => c
+    call s6(pb)
+  end subroutine call_s6
+  subroutine s6(b)
+    type(base), intent(inout) :: b(:)
+    b%i = 42
+  end subroutine s6
 end module



More information about the flang-commits mailing list