diff options
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 34 | ||||
| -rw-r--r-- | clang/test/OpenMP/for_loop_messages.cpp | 16 | 
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  | 

