[flang-commits] [flang] [flang][semantics] add portability warning and tests for copy-in/copy-out case (PR #153263)
Andre Kuhlenschmidt via flang-commits
flang-commits at lists.llvm.org
Wed Aug 27 08:59:26 PDT 2025
https://github.com/akuhlens updated https://github.com/llvm/llvm-project/pull/153263
>From 2128de985bc3c00ef05f0ae1feaa46ceb8fdc6d1 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Tue, 12 Aug 2025 12:44:30 -0700
Subject: [PATCH 1/4] initial commit
---
flang/test/Semantics/call45.f90 | 15 +++++++++++++++
1 file changed, 15 insertions(+)
create mode 100644 flang/test/Semantics/call45.f90
diff --git a/flang/test/Semantics/call45.f90 b/flang/test/Semantics/call45.f90
new file mode 100644
index 0000000000000..aca0767e0ead2
--- /dev/null
+++ b/flang/test/Semantics/call45.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror
+program call45
+ integer :: v(100) = [(i, i=1, 100)]
+ !ERROR: Actual argument associated with VOLATILE dummy argument 'v=' is not definable [-Wundefinable-asynchronous-or-volatile-actual]
+ !BECAUSE: Variable 'v([INTEGER(8)::1_8,2_8,2_8,3_8,3_8,3_8,4_8,4_8,4_8,4_8])' has a vector subscript
+ call sub(v([1,2,2,3,3,3,4,4,4,4]))
+ !OK: Some compilers don't allow this, but there doesn't seem to be a good reason to disallow it.
+ call sub(v(21:30))
+ print *, v
+contains
+ subroutine sub(v)
+ integer, volatile :: v(10)
+ v = 0
+ end subroutine sub
+end program call45
>From dd962e2c080b5ce26aaff59b51072e186730200e Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Thu, 14 Aug 2025 08:46:56 -0700
Subject: [PATCH 2/4] add portability warning
---
flang/include/flang/Evaluate/tools.h | 3 +++
flang/lib/Evaluate/tools.cpp | 4 +++
flang/lib/Semantics/check-call.cpp | 39 ++++++++++++++++++----------
flang/test/Semantics/call45.f90 | 1 +
4 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index e20af008b1baf..b39f78e30541f 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -1104,6 +1104,9 @@ extern template semantics::UnorderedSymbolSet CollectCudaSymbols(
bool HasVectorSubscript(const Expr<SomeType> &);
bool HasVectorSubscript(const ActualArgument &);
+// Predicate: is an expression an expression a section of an array?
+bool IsArraySection(const Expr<SomeType> &expr);
+
// Predicate: does an expression contain constant?
bool HasConstant(const Expr<SomeType> &);
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index aee7457b2566a..e6e215ecb4894 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -1185,6 +1185,10 @@ bool HasVectorSubscript(const ActualArgument &actual) {
return expr && HasVectorSubscript(*expr);
}
+bool IsArraySection(const Expr<SomeType> &expr) {
+ return expr.Rank() > 0 && IsVariable(expr) && !UnwrapWholeSymbolDataRef(expr);
+}
+
// HasConstant()
struct HasConstantHelper : public AnyTraverse<HasConstantHelper, bool,
/*TraverseAssocEntityDetails=*/false> {
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 681f87f1d28e7..113c6b96fcebe 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -779,24 +779,37 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
// Cases when temporaries might be needed but must not be permitted.
bool dummyIsAssumedShape{dummy.type.attrs().test(
characteristics::TypeAndShape::Attr::AssumedShape)};
- if ((actualIsAsynchronous || actualIsVolatile) &&
- (dummyIsAsynchronous || dummyIsVolatile) && !dummyIsValue) {
- if (actualCoarrayRef) { // C1538
- messages.Say(
- "Coindexed ASYNCHRONOUS or VOLATILE actual argument may not be associated with %s with ASYNCHRONOUS or VOLATILE attributes unless VALUE"_err_en_US,
- dummyName);
- }
- if ((actualRank > 0 || actualIsAssumedRank) && !actualIsContiguous) {
- if (dummyIsContiguous ||
- !(dummyIsAssumedShape || dummyIsAssumedRank ||
- (actualIsPointer && dummyIsPointer))) { // C1539 & C1540
+ if (!dummyIsValue && (dummyIsAsynchronous || dummyIsVolatile)) {
+ if (actualIsAsynchronous || actualIsVolatile) {
+ if (actualCoarrayRef) { // C1538
messages.Say(
- "ASYNCHRONOUS or VOLATILE actual argument that is not simply contiguous may not be associated with a contiguous ASYNCHRONOUS or VOLATILE %s"_err_en_US,
+ "Coindexed ASYNCHRONOUS or VOLATILE actual argument may not be associated with %s with ASYNCHRONOUS or VOLATILE attributes unless VALUE"_err_en_US,
dummyName);
}
+ if ((actualRank > 0 || actualIsAssumedRank) && !actualIsContiguous) {
+ if (dummyIsContiguous ||
+ !(dummyIsAssumedShape || dummyIsAssumedRank ||
+ (actualIsPointer && dummyIsPointer))) { // C1539 & C1540
+ messages.Say(
+ "ASYNCHRONOUS or VOLATILE actual argument that is not simply contiguous may not be associated with a contiguous ASYNCHRONOUS or VOLATILE %s"_err_en_US,
+ dummyName);
+ }
+ }
+ // The vector subscript case is handled by the definability check above.
+ // The copy-in/copy-out cases are handled by the previous checks.
+ // Nag, GFortran, and NVFortran all error on this case, even though it is
+ // ok, prossibly as an over-restriction of C1548.
+ } else if (!(dummyIsAssumedShape || dummyIsAssumedRank ||
+ (actualIsPointer && dummyIsPointer)) &&
+ evaluate::IsArraySection(actual) &&
+ !evaluate::HasVectorSubscript(actual)) {
+ context.Warn(common::UsageWarning::ArraySectionCopyInCopyOut,
+ messages.at(),
+ "The array section '%s' may not be associated with %s with %s attribute, unless the dummy is assumed-shape or assumed-rank"_port_en_US,
+ actual.AsFortran(), dummyName,
+ dummyIsAsynchronous ? "ASYNCHRONOUS" : "VOLATILE");
}
}
-
// 15.5.2.6 -- dummy is ALLOCATABLE
bool dummyIsOptional{
dummy.attrs.test(characteristics::DummyDataObject::Attr::Optional)};
diff --git a/flang/test/Semantics/call45.f90 b/flang/test/Semantics/call45.f90
index aca0767e0ead2..1a7523dfae627 100644
--- a/flang/test/Semantics/call45.f90
+++ b/flang/test/Semantics/call45.f90
@@ -5,6 +5,7 @@ program call45
!BECAUSE: Variable 'v([INTEGER(8)::1_8,2_8,2_8,3_8,3_8,3_8,4_8,4_8,4_8,4_8])' has a vector subscript
call sub(v([1,2,2,3,3,3,4,4,4,4]))
!OK: Some compilers don't allow this, but there doesn't seem to be a good reason to disallow it.
+ !PORTABILITY: The array section 'v(21_8:30_8:1_8)' may not be associated with dummy argument 'v=' with VOLATILE attribute, unless the dummy is assumed-shape or assumed-rank [-Warray-section-copy-in-copy-out]
call sub(v(21:30))
print *, v
contains
>From f44df100705af7f0d09acc07d1af0b90b1991d3f Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Wed, 20 Aug 2025 15:14:39 -0700
Subject: [PATCH 3/4] address feedback
---
flang/include/flang/Evaluate/tools.h | 2 +-
flang/lib/Semantics/check-call.cpp | 9 ++++-----
flang/test/Semantics/call45.f90 | 29 +++++++++++++++++++++++++---
3 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index b39f78e30541f..eecb2c1186145 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -1104,7 +1104,7 @@ extern template semantics::UnorderedSymbolSet CollectCudaSymbols(
bool HasVectorSubscript(const Expr<SomeType> &);
bool HasVectorSubscript(const ActualArgument &);
-// Predicate: is an expression an expression a section of an array?
+// Predicate: is an expression a section of an array?
bool IsArraySection(const Expr<SomeType> &expr);
// Predicate: does an expression contain constant?
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 113c6b96fcebe..e4b33294d7202 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -781,7 +781,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
characteristics::TypeAndShape::Attr::AssumedShape)};
if (!dummyIsValue && (dummyIsAsynchronous || dummyIsVolatile)) {
if (actualIsAsynchronous || actualIsVolatile) {
- if (actualCoarrayRef) { // C1538
+ if (actualCoarrayRef) { // F'2023 C1547
messages.Say(
"Coindexed ASYNCHRONOUS or VOLATILE actual argument may not be associated with %s with ASYNCHRONOUS or VOLATILE attributes unless VALUE"_err_en_US,
dummyName);
@@ -789,7 +789,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
if ((actualRank > 0 || actualIsAssumedRank) && !actualIsContiguous) {
if (dummyIsContiguous ||
!(dummyIsAssumedShape || dummyIsAssumedRank ||
- (actualIsPointer && dummyIsPointer))) { // C1539 & C1540
+ (actualIsPointer && dummyIsPointer))) { // F'2023 C1548 & C1549
messages.Say(
"ASYNCHRONOUS or VOLATILE actual argument that is not simply contiguous may not be associated with a contiguous ASYNCHRONOUS or VOLATILE %s"_err_en_US,
dummyName);
@@ -803,9 +803,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
(actualIsPointer && dummyIsPointer)) &&
evaluate::IsArraySection(actual) &&
!evaluate::HasVectorSubscript(actual)) {
- context.Warn(common::UsageWarning::ArraySectionCopyInCopyOut,
- messages.at(),
- "The array section '%s' may not be associated with %s with %s attribute, unless the dummy is assumed-shape or assumed-rank"_port_en_US,
+ context.Warn(common::UsageWarning::Portability, messages.at(),
+ "The array section '%s' should not be associated with %s with %s attribute, unless the dummy is assumed-shape or assumed-rank"_port_en_US,
actual.AsFortran(), dummyName,
dummyIsAsynchronous ? "ASYNCHRONOUS" : "VOLATILE");
}
diff --git a/flang/test/Semantics/call45.f90 b/flang/test/Semantics/call45.f90
index 1a7523dfae627..751b0e91dea44 100644
--- a/flang/test/Semantics/call45.f90
+++ b/flang/test/Semantics/call45.f90
@@ -1,16 +1,39 @@
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror
program call45
- integer :: v(100) = [(i, i=1, 100)]
+ integer, target :: v(100) = [(i, i=1, 100)]
+ integer, pointer :: p(:) => v
!ERROR: Actual argument associated with VOLATILE dummy argument 'v=' is not definable [-Wundefinable-asynchronous-or-volatile-actual]
!BECAUSE: Variable 'v([INTEGER(8)::1_8,2_8,2_8,3_8,3_8,3_8,4_8,4_8,4_8,4_8])' has a vector subscript
call sub(v([1,2,2,3,3,3,4,4,4,4]))
- !OK: Some compilers don't allow this, but there doesn't seem to be a good reason to disallow it.
- !PORTABILITY: The array section 'v(21_8:30_8:1_8)' may not be associated with dummy argument 'v=' with VOLATILE attribute, unless the dummy is assumed-shape or assumed-rank [-Warray-section-copy-in-copy-out]
+ !PORTABILITY: The array section 'v(21_8:30_8:1_8)' should not be associated with dummy argument 'v=' with VOLATILE attribute, unless the dummy is assumed-shape or assumed-rank [-Wportability]
call sub(v(21:30))
+ call sub2(v(21:40:2))
+ call sub4(p)
print *, v
contains
subroutine sub(v)
integer, volatile :: v(10)
v = 0
end subroutine sub
+ subroutine sub1(v)
+ integer, volatile :: v(:)
+ v = 0
+ end subroutine sub1
+ subroutine sub2(v)
+ integer :: v(:)
+ !TODO: This should either be an portability warning or copy-in-copy-out warning
+ call sub(v)
+ call sub1(v)
+ end subroutine sub2
+ subroutine sub3(v)
+ integer, pointer :: v(:)
+ v = 0
+ end subroutine sub3
+ subroutine sub4(v)
+ integer, pointer :: v(:)
+ !TODO: This should either be a portability warning or copy-in-copy-out warning
+ call sub(v)
+ call sub1(v)
+ call sub3(v)
+ end subroutine sub4
end program call45
>From 42bab5bfae80d5ce04615fb777f63bd2bc7d3771 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Wed, 20 Aug 2025 16:09:50 -0700
Subject: [PATCH 4/4] add another test case
---
flang/test/Semantics/call45.f90 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/flang/test/Semantics/call45.f90 b/flang/test/Semantics/call45.f90
index 751b0e91dea44..056ce47189162 100644
--- a/flang/test/Semantics/call45.f90
+++ b/flang/test/Semantics/call45.f90
@@ -7,6 +7,8 @@ program call45
call sub(v([1,2,2,3,3,3,4,4,4,4]))
!PORTABILITY: The array section 'v(21_8:30_8:1_8)' should not be associated with dummy argument 'v=' with VOLATILE attribute, unless the dummy is assumed-shape or assumed-rank [-Wportability]
call sub(v(21:30))
+ !PORTABILITY: The array section 'v(21_8:40_8:2_8)' should not be associated with dummy argument 'v=' with VOLATILE attribute, unless the dummy is assumed-shape or assumed-rank [-Wportability]
+ call sub(v(21:40:2))
call sub2(v(21:40:2))
call sub4(p)
print *, v
More information about the flang-commits
mailing list