@@ -1545,6 +1545,60 @@ class CopyInOutExplicitInterface {
15451545 const characteristics::DummyDataObject &dummyObj_;
15461546};
15471547
1548+ static bool MayNeedCopy (FoldingContext &fc, const ActualArgument &actual,
1549+ const characteristics::DummyDataObject *dummyObj, bool forCopyOut) {
1550+ const bool forCopyIn = !forCopyOut;
1551+ if (!evaluate::IsVariable (actual)) {
1552+ // Actual argument expressions that aren’t variables are copy-in, but
1553+ // not copy-out.
1554+ return forCopyIn;
1555+ }
1556+ if (dummyObj) { // Explict interface
1557+ CopyInOutExplicitInterface check{fc, actual, *dummyObj};
1558+ if (forCopyOut && check.HasIntentIn ()) {
1559+ // INTENT(IN) dummy args never need copy-out
1560+ return false ;
1561+ }
1562+ if (forCopyIn && check.HasIntentOut ()) {
1563+ // INTENT(OUT) dummy args never need copy-in
1564+ return false ;
1565+ }
1566+ if (check.PassByValue ()) {
1567+ // Pass by value, always copy-in, never copy-out
1568+ return forCopyIn;
1569+ }
1570+ if (check.HaveCoarrayDifferences ()) {
1571+ return true ;
1572+ }
1573+ // Note: contiguity and polymorphic checks deal with array or assumed rank
1574+ // arguments
1575+ if (!check.HaveArrayOrAssumedRankArgs ()) {
1576+ return false ;
1577+ }
1578+ if (check.HaveContiguityDifferences ()) {
1579+ return true ;
1580+ }
1581+ if (check.HavePolymorphicDifferences ()) {
1582+ return true ;
1583+ }
1584+ } else { // Implicit interface
1585+ if (ExtractCoarrayRef (actual)) {
1586+ // Coindexed actual args may need copy-in and copy-out with implicit
1587+ // interface
1588+ return true ;
1589+ }
1590+ if (!IsSimplyContiguous (actual, fc)) {
1591+ // Copy-in: actual arguments that are variables are copy-in when
1592+ // non-contiguous.
1593+ // Copy-out: vector subscripts could refer to duplicate elements, can't
1594+ // copy out.
1595+ return forCopyOut ? !HasVectorSubscript (actual) : true ;
1596+ }
1597+ }
1598+ // For everything else, no copy-in or copy-out
1599+ return false ;
1600+ }
1601+
15481602static bool MayNeedCopyIn (FoldingContext &fc, const ActualArgument &actual,
15491603 const characteristics::DummyDataObject *dummyObj) {
15501604 if (!evaluate::IsVariable (actual)) {
@@ -1658,11 +1712,7 @@ bool MayNeedCopy(const ActualArgument *actual,
16581712 const auto *dummyObj{dummy
16591713 ? std::get_if<characteristics::DummyDataObject>(&dummy->u )
16601714 : nullptr };
1661- if (forCopyOut) {
1662- return MayNeedCopyOut (fc, *actual, dummyObj);
1663- } else {
1664- return MayNeedCopyIn (fc, *actual, dummyObj);
1665- }
1715+ return MayNeedCopy (fc, *actual, dummyObj, forCopyOut);
16661716}
16671717
16681718} // namespace Fortran::evaluate
0 commit comments