diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3471,7 +3471,7 @@ 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 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -209,7 +209,7 @@ // 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 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2055,7 +2055,8 @@ 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 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -190,8 +190,31 @@ 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)}) { + // The symbol is null, return early + if (!name->symbol) { + return; + } else 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()); + return; + } 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()); + return; + } else { + alignedNameList.push_back(*name); + } + } + } checkMultipleOcurrence(alignedNameList, itr->second->source, "ALIGNED"); } @@ -2814,8 +2837,9 @@ 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 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -440,8 +440,8 @@ } 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 --- 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 --- 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 @@ 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