diff --git a/flang/lib/Semantics/check-directive-structure.h b/flang/lib/Semantics/check-directive-structure.h --- a/flang/lib/Semantics/check-directive-structure.h +++ b/flang/lib/Semantics/check-directive-structure.h @@ -123,6 +123,7 @@ : context_{context}, directiveClausesMap_(directiveClausesMap) {} virtual ~DirectiveStructureChecker() {} + using ClauseMapTy = std::multimap; struct DirectiveContext { DirectiveContext(parser::CharBlock source, D d) : directiveSource{source}, directive{d} {} @@ -136,7 +137,7 @@ common::EnumSet requiredClauses{}; const PC *clause{nullptr}; - std::multimap clauseInfo; + ClauseMapTy clauseInfo; std::list actualClauses; Symbol *loopIV{nullptr}; }; @@ -205,6 +206,12 @@ return nullptr; } + std::pair + FindClauses(C type) { + auto it{GetContext().clauseInfo.equal_range(type)}; + return it; + } + void PushContext(const parser::CharBlock &source, D dir) { dirContext_.emplace_back(source, dir); } 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 @@ -606,7 +606,24 @@ } } } - // TODO: A list-item cannot appear in more than one aligned clause + // A list-item cannot appear in more than one aligned clause + semantics::SymbolSet alignedVars; + auto clauseAll = FindClauses(llvm::omp::Clause::OMPC_aligned); + for (auto itr = clauseAll.first; itr != clauseAll.second; ++itr) { + const auto &alignedClause{ + std::get(itr->second->u)}; + const auto &alignedNameList{ + std::get>(alignedClause.v.t)}; + for (auto const &var : alignedNameList) { + if (alignedVars.count(*(var.symbol)) == 1) { + context_.Say(itr->second->source, + "List item '%s' present at multiple ALIGNED clauses"_err_en_US, + var.ToString()); + break; + } + alignedVars.insert(*(var.symbol)); + } + } } // SIMD // 2.7.3 Single Construct Restriction diff --git a/flang/test/Semantics/omp-simd-aligned.f90 b/flang/test/Semantics/omp-simd-aligned.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-simd-aligned.f90 @@ -0,0 +1,54 @@ +! RUN: %S/test_errors.sh %s %t %flang -fopenmp + +! OpenMP Version 4.5 +! 2.8.1 simd Construct +! Semantic error for correct test case + +program omp_simd + integer i, j, k + integer, allocatable :: a(:), b(:) + + allocate(a(10)) + allocate(b(10)) + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a, a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !ERROR: List item 'b' present at multiple ALIGNED clauses + !$omp simd aligned(a,a) aligned(b) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) aligned(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !$omp simd aligned(a) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) private(a) aligned(a) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + print *, a + +end program omp_simd