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,24 @@ 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 (const auto *commonBlock{ + 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 { + alignedNameList.push_back(*name); + } + } + } checkMultipleOcurrence(alignedNameList, itr->second->source, "ALIGNED"); } @@ -2814,8 +2830,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 @@ -416,8 +416,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/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 integer, allocatable :: a(:), b(:) + common /cmn/ c allocate(a(10)) allocate(b(10)) @@ -51,4 +52,11 @@ 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 + end program omp_simd