return false;
}
+void OmpStructureChecker::CheckMultListItems() {
+ semantics::UnorderedSymbolSet listVars;
+ auto checkMultipleOcurrence = [&](const std::list<parser::Name> &nameList,
+ const parser::CharBlock &item,
+ const std::string &clauseName) {
+ for (auto const &var : nameList) {
+ if (llvm::is_contained(listVars, *(var.symbol))) {
+ context_.Say(item,
+ "List item '%s' present at multiple %s clauses"_err_en_US,
+ var.ToString(), clauseName);
+ }
+ listVars.insert(*(var.symbol));
+ }
+ };
+
+ // Aligned clause
+ auto alignedClauses{FindClauses(llvm::omp::Clause::OMPC_aligned)};
+ for (auto itr = alignedClauses.first; itr != alignedClauses.second; ++itr) {
+ const auto &alignedClause{
+ std::get<parser::OmpClause::Aligned>(itr->second->u)};
+ const auto &alignedNameList{
+ std::get<std::list<parser::Name>>(alignedClause.v.t)};
+ checkMultipleOcurrence(alignedNameList, itr->second->source, "ALIGNED");
+ }
+
+ // Nontemporal clause
+ auto nonTemporalClauses{FindClauses(llvm::omp::Clause::OMPC_nontemporal)};
+ for (auto itr = nonTemporalClauses.first; itr != nonTemporalClauses.second;
+ ++itr) {
+ const auto &nontempClause{
+ std::get<parser::OmpClause::Nontemporal>(itr->second->u)};
+ const auto &nontempNameList{nontempClause.v};
+ checkMultipleOcurrence(nontempNameList, itr->second->source, "NONTEMPORAL");
+ }
+}
+
bool OmpStructureChecker::HasInvalidWorksharingNesting(
const parser::CharBlock &source, const OmpDirectiveSet &set) {
// set contains all the invalid closely nested directives
}
}
}
- // A list-item cannot appear in more than one aligned clause
- semantics::UnorderedSymbolSet alignedVars;
- auto clauseAll = FindClauses(llvm::omp::Clause::OMPC_aligned);
- for (auto itr = clauseAll.first; itr != clauseAll.second; ++itr) {
- const auto &alignedClause{
- std::get<parser::OmpClause::Aligned>(itr->second->u)};
- const auto &alignedNameList{
- std::get<std::list<parser::Name>>(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));
- }
- }
+ // Sema checks related to presence of multiple list items within the same
+ // clause
+ CheckMultListItems();
} // SIMD
// 2.7.3 Single Construct Restriction
--- /dev/null
+! RUN: %python %S/test_errors.py %s %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 NONTEMPORAL clauses
+ !$omp simd nontemporal(a, a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !ERROR: List item 'b' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a,a) nontemporal(b) nontemporal(b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a) nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ !$omp simd nontemporal(a) nontemporal(b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a) private(a) nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !ERROR: List item 'b' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a,a,b,b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ print *, a
+
+end program omp_simd