diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 34 | ||||
-rw-r--r-- | test/OpenMP/for_loop_messages.cpp | 16 |
3 files changed, 46 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5237456361..238c9eec70 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -9172,6 +9172,8 @@ def err_omp_expected_private_copy_for_allocate : Error< "the referenced item is not found in any private clause on the same directive">; def err_omp_stmt_depends_on_loop_counter : Error< "the loop %select{initializer|condition}0 expression depends on the current loop control variable">; +def err_omp_invariant_or_linear_dependancy : Error< + "expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index a5afce42cb..8aaa1848a6 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -4715,6 +4715,7 @@ class LoopCounterRefChecker final Sema &SemaRef; DSAStackTy &Stack; const ValueDecl *CurLCDecl = nullptr; + const ValueDecl *DepDecl = nullptr; bool IsInitializer = true; public: @@ -4728,6 +4729,18 @@ public: return false; } const auto &&Data = Stack.isLoopControlVariable(VD); + if (DepDecl && Data.first) { + SmallString<128> Name; + llvm::raw_svector_ostream OS(Name); + DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), + /*Qualified=*/true); + SemaRef.Diag(E->getExprLoc(), + diag::err_omp_invariant_or_linear_dependancy) + << OS.str(); + return false; + } + if (Data.first) + DepDecl = VD; return Data.first; } return false; @@ -4742,16 +4755,27 @@ public: return false; } const auto &&Data = Stack.isLoopControlVariable(VD); + if (DepDecl && Data.first) { + SmallString<128> Name; + llvm::raw_svector_ostream OS(Name); + DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), + /*Qualified=*/true); + SemaRef.Diag(E->getExprLoc(), + diag::err_omp_invariant_or_linear_dependancy) + << OS.str(); + return false; + } + if (Data.first) + DepDecl = VD; return Data.first; } return false; } bool VisitStmt(const Stmt *S) { - for (const Stmt *Child : S->children()) { - if (Child && Visit(Child)) - return true; - } - return false; + bool Res = true; + for (const Stmt *Child : S->children()) + Res = Child && Visit(Child) && Res; + return Res; } explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, const ValueDecl *CurLCDecl, bool IsInitializer) diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp index 01c96add28..f3fba6781b 100644 --- a/test/OpenMP/for_loop_messages.cpp +++ b/test/OpenMP/for_loop_messages.cpp @@ -293,6 +293,12 @@ int test_iteration_spaces() { for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1) c[ii] = a[ii]; +// expected-error@+3 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}} +#pragma omp for collapse(2) + for (ii = 10 + 25; ii < 1000; ii += 1) + for (kk = ii * 10 + 25; kk < ii / ii - 23; kk += 1) + ; + #pragma omp parallel // expected-note@+2 {{defined as firstprivate}} // expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}} @@ -603,7 +609,7 @@ int test_with_random_access_iterator() { template <typename IT, int ST> class TC { - int ii; + int ii, iii; public: int dotest_lt(IT begin, IT end) { #pragma omp parallel @@ -614,6 +620,14 @@ public: ; #pragma omp parallel +// expected-error@+4 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}} +// expected-error@+3 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}} +#pragma omp for collapse(2) + for (ii = 10 + 25; ii < 1000; ii += 1) + for (iii = ii * 10 + 25; iii < ii / ii - 23; iii += 1) + ; + +#pragma omp parallel // expected-note@+3 {{loop step is expected to be positive due to this condition}} // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} #pragma omp for |