summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp34
-rw-r--r--clang/test/OpenMP/for_loop_messages.cpp16
3 files changed, 46 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 52374563612..238c9eec70c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/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/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index a5afce42cb3..8aaa1848a60 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/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/clang/test/OpenMP/for_loop_messages.cpp b/clang/test/OpenMP/for_loop_messages.cpp
index 01c96add280..f3fba6781b2 100644
--- a/clang/test/OpenMP/for_loop_messages.cpp
+++ b/clang/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
OpenPOWER on IntegriCloud