Skip to content

Commit a8680be

Browse files
authored
[flang][semantics] add portability warning and tests for copy-in/copy-out case (#153263)
This PR adds some tests and a portability warning around volatility/async, copy-in/copy-out, and definability. It was a NFC until we decided to add the portability warning.
1 parent 98947ff commit a8680be

File tree

4 files changed

+73
-13
lines changed

4 files changed

+73
-13
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,9 @@ extern template semantics::UnorderedSymbolSet CollectCudaSymbols(
11041104
bool HasVectorSubscript(const Expr<SomeType> &);
11051105
bool HasVectorSubscript(const ActualArgument &);
11061106

1107+
// Predicate: is an expression a section of an array?
1108+
bool IsArraySection(const Expr<SomeType> &expr);
1109+
11071110
// Predicate: does an expression contain constant?
11081111
bool HasConstant(const Expr<SomeType> &);
11091112

flang/lib/Evaluate/tools.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,10 @@ bool HasVectorSubscript(const ActualArgument &actual) {
11851185
return expr && HasVectorSubscript(*expr);
11861186
}
11871187

1188+
bool IsArraySection(const Expr<SomeType> &expr) {
1189+
return expr.Rank() > 0 && IsVariable(expr) && !UnwrapWholeSymbolDataRef(expr);
1190+
}
1191+
11881192
// HasConstant()
11891193
struct HasConstantHelper : public AnyTraverse<HasConstantHelper, bool,
11901194
/*TraverseAssocEntityDetails=*/false> {

flang/lib/Semantics/check-call.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -770,24 +770,36 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
770770
// Cases when temporaries might be needed but must not be permitted.
771771
bool dummyIsAssumedShape{dummy.type.attrs().test(
772772
characteristics::TypeAndShape::Attr::AssumedShape)};
773-
if ((actualIsAsynchronous || actualIsVolatile) &&
774-
(dummyIsAsynchronous || dummyIsVolatile) && !dummyIsValue) {
775-
if (actualCoarrayRef) { // C1538
776-
messages.Say(
777-
"Coindexed ASYNCHRONOUS or VOLATILE actual argument may not be associated with %s with ASYNCHRONOUS or VOLATILE attributes unless VALUE"_err_en_US,
778-
dummyName);
779-
}
780-
if ((actualRank > 0 || actualIsAssumedRank) && !actualIsContiguous) {
781-
if (dummyIsContiguous ||
782-
!(dummyIsAssumedShape || dummyIsAssumedRank ||
783-
(actualIsPointer && dummyIsPointer))) { // C1539 & C1540
773+
if (!dummyIsValue && (dummyIsAsynchronous || dummyIsVolatile)) {
774+
if (actualIsAsynchronous || actualIsVolatile) {
775+
if (actualCoarrayRef) { // F'2023 C1547
784776
messages.Say(
785-
"ASYNCHRONOUS or VOLATILE actual argument that is not simply contiguous may not be associated with a contiguous ASYNCHRONOUS or VOLATILE %s"_err_en_US,
777+
"Coindexed ASYNCHRONOUS or VOLATILE actual argument may not be associated with %s with ASYNCHRONOUS or VOLATILE attributes unless VALUE"_err_en_US,
786778
dummyName);
787779
}
780+
if ((actualRank > 0 || actualIsAssumedRank) && !actualIsContiguous) {
781+
if (dummyIsContiguous ||
782+
!(dummyIsAssumedShape || dummyIsAssumedRank ||
783+
(actualIsPointer && dummyIsPointer))) { // F'2023 C1548 & C1549
784+
messages.Say(
785+
"ASYNCHRONOUS or VOLATILE actual argument that is not simply contiguous may not be associated with a contiguous ASYNCHRONOUS or VOLATILE %s"_err_en_US,
786+
dummyName);
787+
}
788+
}
789+
// The vector subscript case is handled by the definability check above.
790+
// The copy-in/copy-out cases are handled by the previous checks.
791+
// Nag, GFortran, and NVFortran all error on this case, even though it is
792+
// ok, prossibly as an over-restriction of C1548.
793+
} else if (!(dummyIsAssumedShape || dummyIsAssumedRank ||
794+
(actualIsPointer && dummyIsPointer)) &&
795+
evaluate::IsArraySection(actual) &&
796+
!evaluate::HasVectorSubscript(actual)) {
797+
context.Warn(common::UsageWarning::Portability, messages.at(),
798+
"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,
799+
actual.AsFortran(), dummyName,
800+
dummyIsAsynchronous ? "ASYNCHRONOUS" : "VOLATILE");
788801
}
789802
}
790-
791803
// 15.5.2.6 -- dummy is ALLOCATABLE
792804
bool dummyIsOptional{
793805
dummy.attrs.test(characteristics::DummyDataObject::Attr::Optional)};

flang/test/Semantics/call45.f90

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror
2+
program call45
3+
integer, target :: v(100) = [(i, i=1, 100)]
4+
integer, pointer :: p(:) => v
5+
!ERROR: Actual argument associated with VOLATILE dummy argument 'v=' is not definable [-Wundefinable-asynchronous-or-volatile-actual]
6+
!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
7+
call sub(v([1,2,2,3,3,3,4,4,4,4]))
8+
!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]
9+
call sub(v(21:30))
10+
!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]
11+
call sub(v(21:40:2))
12+
call sub2(v(21:40:2))
13+
call sub4(p)
14+
print *, v
15+
contains
16+
subroutine sub(v)
17+
integer, volatile :: v(10)
18+
v = 0
19+
end subroutine sub
20+
subroutine sub1(v)
21+
integer, volatile :: v(:)
22+
v = 0
23+
end subroutine sub1
24+
subroutine sub2(v)
25+
integer :: v(:)
26+
!TODO: This should either be an portability warning or copy-in-copy-out warning
27+
call sub(v)
28+
call sub1(v)
29+
end subroutine sub2
30+
subroutine sub3(v)
31+
integer, pointer :: v(:)
32+
v = 0
33+
end subroutine sub3
34+
subroutine sub4(v)
35+
integer, pointer :: v(:)
36+
!TODO: This should either be a portability warning or copy-in-copy-out warning
37+
call sub(v)
38+
call sub1(v)
39+
call sub3(v)
40+
end subroutine sub4
41+
end program call45

0 commit comments

Comments
 (0)