diff --git a/flang/lib/Semantics/check-allocate.cpp b/flang/lib/Semantics/check-allocate.cpp index 7bfd86262b3d6..b4c5660670579 100644 --- a/flang/lib/Semantics/check-allocate.cpp +++ b/flang/lib/Semantics/check-allocate.cpp @@ -618,6 +618,13 @@ bool AllocationCheckerHelper::RunChecks(SemanticsContext &context) { "Object in ALLOCATE must have PINNED attribute when PINNED option is specified"_err_en_US); } } + if (allocateInfo_.gotStream) { + std::optional cudaAttr{GetCUDADataAttr(ultimate_)}; + if (!cudaAttr || *cudaAttr != common::CUDADataAttr::Device) { + context.Say(name_.source, + "Object in ALLOCATE must have DEVICE attribute when STREAM option is specified"_err_en_US); + } + } return RunCoarrayRelatedChecks(context); } diff --git a/flang/test/Lower/CUDA/cuda-allocatable.cuf b/flang/test/Lower/CUDA/cuda-allocatable.cuf index adbf1722731af..eff5f13669e90 100644 --- a/flang/test/Lower/CUDA/cuda-allocatable.cuf +++ b/flang/test/Lower/CUDA/cuda-allocatable.cuf @@ -68,21 +68,21 @@ end subroutine ! CHECK: } subroutine sub4() - real, allocatable, unified :: a(:) + real, allocatable, device :: a(:) integer :: istream allocate(a(10), stream=istream) end subroutine ! CHECK-LABEL: func.func @_QPsub4() ! CHECK: %[[BOX:.*]] = fir.alloca !fir.box>> {bindc_name = "a", uniq_name = "_QFsub4Ea"} -! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %0 {cuda_attr = #fir.cuda, fortran_attrs = #fir.var_attrs, uniq_name = "_QFsub4Ea"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %0 {cuda_attr = #fir.cuda, fortran_attrs = #fir.var_attrs, uniq_name = "_QFsub4Ea"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[ISTREAM:.*]] = fir.alloca i32 {bindc_name = "istream", uniq_name = "_QFsub4Eistream"} ! CHECK: %[[ISTREAM_DECL:.*]]:2 = hlfir.declare %[[ISTREAM]] {uniq_name = "_QFsub4Eistream"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.call @_FortranAAllocatableSetBounds ! CHECK: %[[STREAM:.*]] = fir.load %[[ISTREAM_DECL]]#0 : !fir.ref -! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref>>> stream(%[[STREAM]] : i32) {cuda_attr = #fir.cuda} -> i32 +! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref>>> stream(%[[STREAM]] : i32) {cuda_attr = #fir.cuda} -> i32 ! CHECK: fir.if %{{.*}} { -! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref>>> {cuda_attr = #fir.cuda} -> i32 +! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref>>> {cuda_attr = #fir.cuda} -> i32 ! CHECK: } subroutine sub5() diff --git a/flang/test/Parser/cuf-sanity-common b/flang/test/Parser/cuf-sanity-common index 7f4217fb58355..b097a6aa30045 100644 --- a/flang/test/Parser/cuf-sanity-common +++ b/flang/test/Parser/cuf-sanity-common @@ -32,6 +32,6 @@ module m call globalsub<<<1, 2>>> call globalsub<<<1, 2, 3>>> call globalsub<<<1, 2, 3, 4>>> - allocate(pa(32), stream = 1, pinned = isPinned) + allocate(pa(32), pinned = isPinned) end subroutine end module diff --git a/flang/test/Parser/cuf-sanity-tree.CUF b/flang/test/Parser/cuf-sanity-tree.CUF index dc12759d3ce52..2820441d5b5f0 100644 --- a/flang/test/Parser/cuf-sanity-tree.CUF +++ b/flang/test/Parser/cuf-sanity-tree.CUF @@ -199,8 +199,6 @@ include "cuf-sanity-common" !CHECK: | | | | | | AllocateShapeSpec !CHECK: | | | | | | | Scalar -> Integer -> Expr = '32_4' !CHECK: | | | | | | | | LiteralConstant -> IntLiteralConstant = '32' -!CHECK: | | | | | AllocOpt -> Stream -> Scalar -> Integer -> Expr = '1_4' -!CHECK: | | | | | | LiteralConstant -> IntLiteralConstant = '1' !CHECK: | | | | | AllocOpt -> Pinned -> Scalar -> Logical -> Variable = 'ispinned' !CHECK: | | | | | | Designator -> DataRef -> Name = 'ispinned' !CHECK: | | | EndSubroutineStmt -> diff --git a/flang/test/Parser/cuf-sanity-unparse.CUF b/flang/test/Parser/cuf-sanity-unparse.CUF index 7ac39448d7bd4..b6921e74fc05a 100644 --- a/flang/test/Parser/cuf-sanity-unparse.CUF +++ b/flang/test/Parser/cuf-sanity-unparse.CUF @@ -37,6 +37,6 @@ include "cuf-sanity-common" !CHECK: CALL globalsub<<<1_4,2_4>>>() !CHECK: CALL globalsub<<<1_4,2_4,3_4>>>() !CHECK: CALL globalsub<<<1_4,2_4,3_4,4_4>>>() -!CHECK: ALLOCATE(pa(32_4), STREAM=1_4, PINNED=ispinned) +!CHECK: ALLOCATE(pa(32_4), PINNED=ispinned) !CHECK: END SUBROUTINE !CHECK: END MODULE diff --git a/flang/test/Semantics/cuf07.cuf b/flang/test/Semantics/cuf07.cuf index 91a78e124c593..c48abb5adf0d4 100644 --- a/flang/test/Semantics/cuf07.cuf +++ b/flang/test/Semantics/cuf07.cuf @@ -31,4 +31,12 @@ module m !ERROR: Object in ALLOCATE must have PINNED attribute when PINNED option is specified allocate(ia(100), pinned = plog) end subroutine + + subroutine host2() + integer, allocatable, pinned :: ia(:) + integer :: istream + + !ERROR: Object in ALLOCATE must have DEVICE attribute when STREAM option is specified + allocate(ia(100), stream = istream) + end subroutine end module