diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 1bac91ce477a9..404058962c944 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3471,7 +3471,7 @@ struct OmpIfClause { struct OmpAlignedClause { TUPLE_CLASS_BOILERPLATE(OmpAlignedClause); CharBlock source; - std::tuple, std::optional> t; + std::tuple> t; }; // 2.9.5 order-clause -> ORDER ([order-modifier :]concurrent) diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 6a5815236768c..7baf96c1658c8 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -209,7 +209,7 @@ TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US, // 2.8.1 ALIGNED (list: alignment) TYPE_PARSER(construct( - nonemptyList(name), maybe(":" >> scalarIntConstantExpr))) + Parser{}, maybe(":" >> scalarIntConstantExpr))) // 2.9.5 ORDER ([order-modifier :]concurrent) TYPE_PARSER(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 86ee4af157b64..69e1d994a17e1 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2055,7 +2055,8 @@ class UnparseVisitor { Walk(std::get(x.t)); } void Unparse(const OmpAlignedClause &x) { - Walk(std::get>(x.t), ","); + Walk(std::get(x.t)); + Put(","); Walk(std::get>(x.t)); } void Unparse(const OmpIfClause &x) { diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index c84ad3ffcbbdc..7337102d40e8e 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -190,8 +190,32 @@ void OmpStructureChecker::CheckMultListItems() { for (auto itr = alignedClauses.first; itr != alignedClauses.second; ++itr) { const auto &alignedClause{ std::get(itr->second->u)}; - const auto &alignedNameList{ - std::get>(alignedClause.v.t)}; + const auto &alignedList{std::get<0>(alignedClause.v.t)}; + std::list alignedNameList; + for (const auto &ompObject : alignedList.v) { + if (const auto *name{parser::Unwrap(ompObject)}) { + if (name->symbol) { + if (FindCommonBlockContaining(*(name->symbol))) { + context_.Say(itr->second->source, + "'%s' is a common block name and can not appear in an " + "ALIGNED clause"_err_en_US, + name->ToString()); + } else if (!(IsBuiltinCPtr(*(name->symbol)) || + IsAllocatableOrPointer( + (name->symbol->GetUltimate())))) { + context_.Say(itr->second->source, + "'%s' in ALIGNED clause must be of type C_PTR, POINTER or " + "ALLOCATABLE"_err_en_US, + name->ToString()); + } else { + alignedNameList.push_back(*name); + } + } else { + // The symbol is null, return early + return; + } + } + } checkMultipleOcurrence(alignedNameList, itr->second->source, "ALIGNED"); } @@ -2815,8 +2839,9 @@ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList( parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>; // Clauses with OmpObjectList in the tuple - using TupleObjectListClauses = std::tuple; + using TupleObjectListClauses = + std::tuple; // TODO:: Generate the tuples using TableGen. // Handle other constructs with OmpObjectList such as OpenMPThreadprivate. diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 4b0892a5760ca..70b81117b5c8b 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -440,8 +440,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { } bool Pre(const parser::OmpAlignedClause &x) { - const auto &alignedNameList{std::get>(x.t)}; - ResolveOmpNameList(alignedNameList, Symbol::Flag::OmpAligned); + const auto &alignedNameList{std::get(x.t)}; + ResolveOmpObjectList(alignedNameList, Symbol::Flag::OmpAligned); return false; } diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90 index e641493a2ccc3..976bfe6e6f785 100644 --- a/flang/test/Semantics/OpenMP/clause-validity01.f90 +++ b/flang/test/Semantics/OpenMP/clause-validity01.f90 @@ -6,7 +6,10 @@ ! 2.7.1 Loop construct ! ... + use iso_c_binding integer :: b = 128 + integer, allocatable :: allc + type(C_PTR) :: cpt integer :: z, c = 32 integer, parameter :: num = 16 real(8) :: arrayA(256), arrayB(512) @@ -367,7 +370,7 @@ enddo !ERROR: The parameter of the ALIGNED clause must be a constant positive integer expression - !$omp simd aligned(b:-2) + !$omp simd aligned(cpt:-2) do i = 1, N a = 3.14 enddo @@ -550,11 +553,12 @@ a = 3.14 enddo + allocate(allc) !ERROR: The parameter of the SIMDLEN clause must be a constant positive integer expression !ERROR: The parameter of the ALIGNED clause must be a constant positive integer expression - !$omp taskloop simd simdlen(-1) aligned(a:-2) + !$omp taskloop simd simdlen(-1) aligned(allc:-2) do i = 1, N - a = 3.14 + allc = 3.14 enddo !$omp target enter data map(alloc:A) device(0) diff --git a/flang/test/Semantics/OpenMP/simd-aligned.f90 b/flang/test/Semantics/OpenMP/simd-aligned.f90 index 9b42118e2e1e4..0a9f95833e22e 100644 --- a/flang/test/Semantics/OpenMP/simd-aligned.f90 +++ b/flang/test/Semantics/OpenMP/simd-aligned.f90 @@ -5,8 +5,9 @@ ! Semantic error for correct test case program omp_simd - integer i, j, k + integer i, j, k, c, d(100) integer, allocatable :: a(:), b(:) + common /cmn/ c allocate(a(10)) allocate(b(10)) @@ -51,4 +52,17 @@ program omp_simd print *, a + !ERROR: 'c' is a common block name and can not appear in an ALIGNED clause + !$omp simd aligned(c) + do i = 1, 10 + c = 5 + end do + !$omp end simd + + !ERROR: 'd' in ALIGNED clause must be of type C_PTR, POINTER or ALLOCATABLE + !$omp simd aligned(d:100) + do i = 1, 100 + d(i) = i + end do + end program omp_simd