Index: flang/lib/Evaluate/intrinsics.cpp =================================================================== --- flang/lib/Evaluate/intrinsics.cpp +++ flang/lib/Evaluate/intrinsics.cpp @@ -1067,6 +1067,16 @@ static const IntrinsicInterface intrinsicSubroutine[]{ {"abort", {}, {}, Rank::elemental, IntrinsicClass::impureSubroutine}, + {"co_sum", + {{"a", AnyNumeric, Rank::anyOrAssumedRank, Optionality::required, + common::Intent::InOut}, + {"result_image", AnyInt, Rank::scalar, Optionality::optional, + common::Intent::In}, + {"stat", AnyInt, Rank::scalar, Optionality::optional, + common::Intent::Out}, + {"errmsg", DefaultChar, Rank::scalar, Optionality::optional, + common::Intent::InOut}}, + {}, Rank::elemental, IntrinsicClass::collectiveSubroutine}, {"cpu_time", {{"time", AnyReal, Rank::scalar, Optionality::required, common::Intent::Out}}, @@ -1622,6 +1632,35 @@ } } + // Check and restrict coindexed objects being passed to certain arguments + // in the collective subroutines and move_alloc + // TODO: Add rest of collective subroutines to this check as they are + // added to the list of intrinsic subroutines + if (std::strcmp(name, "move_alloc") == 0 || + std::strcmp(name, "co_sum") == 0) { + for (std::size_t j{0}; j < dummies; ++j) { + const ActualArgument *arg{actualForDummy[j]}; + if (arg) { + const IntrinsicDummyArgument &d{ + dummy[std::min(j, dummyArgPatterns - 1)]}; + const char *dummyName(d.keyword); + if (std::strcmp(dummyName, "a") == 0 || + std::strcmp(dummyName, "stat") == 0 || + std::strcmp(dummyName, "errmsg") == 0 || + std::strcmp(dummyName, "from") == 0 || + std::strcmp(dummyName, "to") == 0) { + if (const auto *expr{arg->UnwrapExpr()}) { + if (ExtractCoarrayRef(*expr)) { + context.messages().Say(arg->sourceLocation(), + "'%s' argument to '%s' may not be a coindexed object"_err_en_US, + dummyName, name); + } + } + } + } + } + } + // Calculate the characteristics of the function result, if any std::optional resultType; if (auto category{result.categorySet.LeastElement()}) { Index: flang/test/Semantics/collectives01.f90 =================================================================== --- flang/test/Semantics/collectives01.f90 +++ flang/test/Semantics/collectives01.f90 @@ -1,8 +1,6 @@ ! RUN: %python %S/test_errors.py %s %flang_fc1 -! XFAIL: * ! This test checks for semantic errors in co_sum subroutine calls based on ! the co_reduce interface defined in section 16.9.50 of the Fortran 2018 standard. -! To Do: add co_sum to the list of intrinsics program test_co_sum implicit none @@ -52,6 +50,9 @@ !ERROR: missing mandatory 'a=' argument call co_sum(result_image=1, stat=status, errmsg=message) + !ERROR: repeated keyword argument to intrinsic 'co_sum' + call co_sum(a=i, a=c) + ! argument 'a' shall be of numeric type !ERROR: Actual argument for 'a=' has bad type 'LOGICAL(4)' call co_sum(bool) @@ -60,8 +61,7 @@ !ERROR: Actual argument associated with INTENT(IN OUT) dummy argument 'a=' must be definable call co_sum(a=1+1) - ! argument 'a' shall not be a coindexed object - !ERROR: to be determined + !ERROR: 'a' argument to 'co_sum' may not be a coindexed object call co_sum(a=coindexed_real[1]) ! 'result_image' argument shall be a integer @@ -76,8 +76,7 @@ !ERROR: Actual argument associated with INTENT(OUT) dummy argument 'stat=' must be definable call co_sum(a=i, result_image=1, stat=1+1, errmsg=message) - ! 'stat' argument shall be noncoindexed - !ERROR: to be determined + !ERROR: 'stat' argument to 'co_sum' may not be a coindexed object call co_sum(d, stat=coindexed_integer[1]) ! 'stat' argument shall be an integer @@ -92,8 +91,7 @@ !ERROR: Actual argument associated with INTENT(IN OUT) dummy argument 'errmsg=' must be definable call co_sum(a=i, result_image=1, stat=status, errmsg='c') - ! 'errmsg' argument shall be noncoindexed - !ERROR: to be determined + !ERROR: 'errmsg' argument to 'co_sum' may not be a coindexed object call co_sum(c, errmsg=coindexed_character[1]) ! 'errmsg' argument shall be character scalar Index: flang/test/Semantics/move_alloc.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/move_alloc.f90 @@ -0,0 +1,31 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Check for semantic errors in move_alloc() subroutine calls +program main + integer, allocatable :: a(:)[:], b(:)[:], c(:)[:], d(:)[:] + !ERROR: 'e' is an ALLOCATABLE coarray and must have a deferred coshape + integer, allocatable :: e(:)[*] + integer status, coindexed_status[*] + character(len=1) message, coindexed_message[*] + + ! standards conforming + allocate(a(3)[*]) + a = [ 1, 2, 3 ] + call move_alloc(a, b, status, message) + + allocate(c(3)[*]) + c = [ 1, 2, 3 ] + + ! standards non-conforming + !ERROR: 'from' argument to 'move_alloc' may not be a coindexed object + call move_alloc(c[1], d) + + !ERROR: 'to' argument to 'move_alloc' may not be a coindexed object + call move_alloc(c, d[1]) + + !ERROR: 'stat' argument to 'move_alloc' may not be a coindexed object + call move_alloc(c, d, coindexed_status[1]) + + !ERROR: 'errmsg' argument to 'move_alloc' may not be a coindexed object + call move_alloc(c, d, status, coindexed_message[1]) + +end program main