Skip to content

Commit c87cd13

Browse files
committed
[flang] Catch non-CONTIGUOUS assumed-rank with ASYNCHRONOUS/VOLATILE 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 890335b commit c87cd13

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
@@ -463,22 +463,27 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
463463
: nullptr};
464464
int actualRank{actualType.Rank()};
465465
bool actualIsPointer{evaluate::IsObjectPointer(actual)};
466+
bool actualIsAssumedRank{evaluate::IsAssumedRank(actual)};
466467
if (dummy.type.attrs().test(
467468
characteristics::TypeAndShape::Attr::AssumedShape)) {
468469
// 15.5.2.4(16)
469-
if (actualRank == 0) {
470+
if (actualIsAssumedRank) {
471+
messages.Say(
472+
"Assumed-rank actual argument may not be associated with assumed-shape %s"_err_en_US,
473+
dummyName);
474+
} else if (actualRank == 0) {
470475
messages.Say(
471476
"Scalar actual argument may not be associated with assumed-shape %s"_err_en_US,
472477
dummyName);
473-
}
474-
if (actualIsAssumedSize && actualLastSymbol) {
478+
} else if (actualIsAssumedSize && actualLastSymbol) {
475479
evaluate::SayWithDeclaration(messages, *actualLastSymbol,
476480
"Assumed-size array may not be associated with assumed-shape %s"_err_en_US,
477481
dummyName);
478482
}
479483
} else if (dummyRank > 0) {
480484
bool basicError{false};
481-
if (actualRank == 0 && !dummyIsAllocatableOrPointer) {
485+
if (actualRank == 0 && !actualIsAssumedRank &&
486+
!dummyIsAllocatableOrPointer) {
482487
// Actual is scalar, dummy is an array. F'2023 15.5.2.5p14
483488
if (actualIsCoindexed) {
484489
basicError = true;
@@ -531,7 +536,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
531536
characteristics::DummyDataObject::Attr::DeducedFromActual)) {
532537
if (auto dummySize{evaluate::ToInt64(evaluate::Fold(foldingContext,
533538
evaluate::GetSize(evaluate::Shape{dummy.type.shape()})))}) {
534-
if (actualRank == 0) {
539+
if (actualRank == 0 && !actualIsAssumedRank) {
535540
if (evaluate::IsArrayElement(actual)) {
536541
// Actual argument is a scalar array element
537542
evaluate::DesignatorFolder folder{
@@ -568,7 +573,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
568573
}
569574
}
570575
}
571-
} else { // actualRank > 0
576+
} else { // actualRank > 0 || actualIsAssumedRank
572577
if (auto actualSize{evaluate::ToInt64(evaluate::Fold(foldingContext,
573578
evaluate::GetSize(evaluate::Shape(actualType.shape()))))};
574579
actualSize && *actualSize < *dummySize) {
@@ -644,7 +649,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
644649
"Coindexed ASYNCHRONOUS or VOLATILE actual argument may not be associated with %s with ASYNCHRONOUS or VOLATILE attributes unless VALUE"_err_en_US,
645650
dummyName);
646651
}
647-
if (actualRank > 0 && !actualIsContiguous) {
652+
if ((actualRank > 0 || actualIsAssumedRank) && !actualIsContiguous) {
648653
if (dummyIsContiguous ||
649654
!(dummyIsAssumedShape || dummyIsAssumedRank ||
650655
(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)