Skip to content

Commit 9652e9b

Browse files
authored
[flang] Catch non-CONTIGUOUS assumed-rank with ASYNCHRONOUS/VOLATILE … (#71243)
…forwarded to CONTIGUOUS dummy No object with the ASYNCHRONOUS or VOLATILE attribute can go through the copy-in/copy-out protocol necessary for argument association with a contiguous dummy array argument. The check for this constraint missed the case of an assumed-rank array without an explicit CONTIGUOUS attribute being forwarded on to a CONTIGUOUS dummy argument.
1 parent 63d19cf commit 9652e9b

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

flang/lib/Semantics/check-call.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -464,22 +464,27 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
464464
: nullptr};
465465
int actualRank{actualType.Rank()};
466466
bool actualIsPointer{evaluate::IsObjectPointer(actual)};
467+
bool actualIsAssumedRank{evaluate::IsAssumedRank(actual)};
467468
if (dummy.type.attrs().test(
468469
characteristics::TypeAndShape::Attr::AssumedShape)) {
469470
// 15.5.2.4(16)
470-
if (actualRank == 0) {
471+
if (actualIsAssumedRank) {
472+
messages.Say(
473+
"Assumed-rank actual argument may not be associated with assumed-shape %s"_err_en_US,
474+
dummyName);
475+
} else if (actualRank == 0) {
471476
messages.Say(
472477
"Scalar actual argument may not be associated with assumed-shape %s"_err_en_US,
473478
dummyName);
474-
}
475-
if (actualIsAssumedSize && actualLastSymbol) {
479+
} else if (actualIsAssumedSize && actualLastSymbol) {
476480
evaluate::SayWithDeclaration(messages, *actualLastSymbol,
477481
"Assumed-size array may not be associated with assumed-shape %s"_err_en_US,
478482
dummyName);
479483
}
480484
} else if (dummyRank > 0) {
481485
bool basicError{false};
482-
if (actualRank == 0 && !dummyIsAllocatableOrPointer) {
486+
if (actualRank == 0 && !actualIsAssumedRank &&
487+
!dummyIsAllocatableOrPointer) {
483488
// Actual is scalar, dummy is an array. F'2023 15.5.2.5p14
484489
if (actualIsCoindexed) {
485490
basicError = true;
@@ -532,7 +537,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
532537
characteristics::DummyDataObject::Attr::DeducedFromActual)) {
533538
if (auto dummySize{evaluate::ToInt64(evaluate::Fold(foldingContext,
534539
evaluate::GetSize(evaluate::Shape{dummy.type.shape()})))}) {
535-
if (actualRank == 0) {
540+
if (actualRank == 0 && !actualIsAssumedRank) {
536541
if (evaluate::IsArrayElement(actual)) {
537542
// Actual argument is a scalar array element
538543
evaluate::DesignatorFolder folder{
@@ -569,7 +574,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
569574
}
570575
}
571576
}
572-
} else { // actualRank > 0
577+
} else { // actualRank > 0 || actualIsAssumedRank
573578
if (auto actualSize{evaluate::ToInt64(evaluate::Fold(foldingContext,
574579
evaluate::GetSize(evaluate::Shape(actualType.shape()))))};
575580
actualSize && *actualSize < *dummySize) {
@@ -645,7 +650,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
645650
"Coindexed ASYNCHRONOUS or VOLATILE actual argument may not be associated with %s with ASYNCHRONOUS or VOLATILE attributes unless VALUE"_err_en_US,
646651
dummyName);
647652
}
648-
if (actualRank > 0 && !actualIsContiguous) {
653+
if ((actualRank > 0 || actualIsAssumedRank) && !actualIsContiguous) {
649654
if (dummyIsContiguous ||
650655
!(dummyIsAssumedShape || dummyIsAssumedRank ||
651656
(actualIsPointer && dummyIsPointer))) { // C1539 & C1540

flang/test/Semantics/call03.f90

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,11 +345,12 @@ subroutine test14(a,b,c,d) ! C1538
345345
call volatile(d[1])
346346
end subroutine
347347

348-
subroutine test15() ! C1539
348+
subroutine test15(assumedrank) ! C1539
349349
real, pointer :: a(:)
350350
real, asynchronous :: b(10)
351351
real, volatile :: c(10)
352352
real, asynchronous, volatile :: d(10)
353+
real, asynchronous, volatile :: assumedrank(..)
353354
call assumedsize(a(::2)) ! ok
354355
call contiguous(a(::2)) ! ok
355356
call valueassumedsize(a(::2)) ! ok
@@ -368,6 +369,8 @@ subroutine test15() ! C1539
368369
call volatileassumedsize(d(::2))
369370
!ERROR: ASYNCHRONOUS or VOLATILE actual argument that is not simply contiguous may not be associated with a contiguous dummy argument 'x='
370371
call volatilecontiguous(d(::2))
372+
!ERROR: ASYNCHRONOUS or VOLATILE actual argument that is not simply contiguous may not be associated with a contiguous dummy argument 'x='
373+
call volatilecontiguous(assumedrank)
371374
end subroutine
372375

373376
subroutine test16() ! C1540

0 commit comments

Comments
 (0)