From 9f4aa8c03413adc6d5946f33c39697c6961680f2 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 24 Jun 2014 12:55:56 +0000 Subject: [PATCH] [OPENMP] Additional checking for 'collapse' clause. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211589 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/StmtOpenMP.h | 43 +++++++++++++++++- include/clang/Basic/DiagnosticSemaKinds.td | 5 ++- lib/Sema/SemaOpenMP.cpp | 51 ++++++++++++++++++---- test/OpenMP/for_ast_print.cpp | 8 +++- test/OpenMP/for_collapse_messages.cpp | 16 ++++--- test/OpenMP/for_misc_messages.c | 27 ++++++------ test/OpenMP/simd_collapse_messages.cpp | 16 ++++--- test/OpenMP/simd_misc_messages.c | 28 ++++++------ 8 files changed, 142 insertions(+), 52 deletions(-) diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index f8ba48ab05..70a914f999 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -67,8 +67,9 @@ protected: OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses, unsigned NumChildren) - : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc), - NumClauses(NumClauses), NumChildren(NumChildren), + : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), + EndLoc(std::move(EndLoc)), NumClauses(NumClauses), + NumChildren(NumChildren), ClausesOffset(llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf())) {} @@ -85,6 +86,44 @@ protected: void setAssociatedStmt(Stmt *S) { *child_begin() = S; } public: + /// \brief Iterates over a filtered subrange of clauses applied to a + /// directive. + /// + /// This iterator visits only those declarations that meet some run-time + /// criteria. + template class filtered_clause_iterator { + ArrayRef::const_iterator Current; + ArrayRef::const_iterator End; + void SkipToNextClause() { + while (Current != End && !FilterPredicate()(*Current)) + ++Current; + } + + public: + typedef const OMPClause *value_type; + filtered_clause_iterator() : Current(), End() {} + explicit filtered_clause_iterator(ArrayRef Arr) + : Current(Arr.begin()), End(Arr.end()) { + SkipToNextClause(); + } + value_type operator*() const { return *Current; } + value_type operator->() const { return *Current; } + filtered_clause_iterator &operator++() { + ++Current; + SkipToNextClause(); + return *this; + } + + filtered_clause_iterator operator++(int) { + filtered_clause_iterator tmp(*this); + ++(*this); + return tmp; + } + + bool operator!() { return Current == End; } + operator bool() { return Current != End; } + }; + /// \brief Returns starting location of directive kind. SourceLocation getLocStart() const { return StartLoc; } /// \brief Returns ending location of directive. diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 98745ca9b8..a189330d57 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -7020,7 +7020,10 @@ def note_omp_predetermined_dsa : Note< def err_omp_loop_var_dsa : Error< "loop iteration variable may not be %0">; def err_omp_not_for : Error< - "statement after '#pragma omp %0' must be a for loop">; + "%select{statement after '#pragma omp %1' must be a for loop|" + "expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">; +def note_omp_collapse_expr : Note< + "as specified in 'collapse' clause">; def err_omp_negative_expression_in_clause : Error< "argument to '%0' clause must be a positive integer value">; def err_omp_not_integral : Error< diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 561251c256..16def4ec90 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1391,13 +1391,22 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { /// \brief Called on a for stmt to check and extract its iteration space /// for further processing (such as collapsing). static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, - Sema &SemaRef, DSAStackTy &DSA) { + Sema &SemaRef, DSAStackTy &DSA, + unsigned CurrentNestedLoopCount, + unsigned NestedLoopCount, + Expr *NestedLoopCountExpr) { // OpenMP [2.6, Canonical Loop Form] // for (init-expr; test-expr; incr-expr) structured-block auto For = dyn_cast_or_null(S); if (!For) { SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) - << getOpenMPDirectiveName(DKind); + << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind) + << NestedLoopCount << (CurrentNestedLoopCount > 0) + << CurrentNestedLoopCount; + if (NestedLoopCount > 1) + SemaRef.Diag(NestedLoopCountExpr->getExprLoc(), + diag::note_omp_collapse_expr) + << NestedLoopCountExpr->getSourceRange(); return true; } assert(For->getBody()); @@ -1491,14 +1500,21 @@ static Stmt *IgnoreContainerStmts(Stmt *S, bool IgnoreCaptured) { } /// \brief Called on a for stmt to check itself and nested loops (if any). -static bool CheckOpenMPLoop(OpenMPDirectiveKind DKind, unsigned NestedLoopCount, +static bool CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA) { + unsigned NestedLoopCount = 1; + if (NestedLoopCountExpr) { + // Found 'collapse' clause - calculate collapse number. + llvm::APSInt Result; + if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) + NestedLoopCount = Result.getLimitedValue(); + } // This is helper routine for loop directives (e.g., 'for', 'simd', // 'for simd', etc.). - assert(NestedLoopCount == 1); Stmt *CurStmt = IgnoreContainerStmts(AStmt, true); for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { - if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA)) + if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, + NestedLoopCount, NestedLoopCountExpr)) return true; // Move on to the next nested for loop, or to the loop body. CurStmt = IgnoreContainerStmts(cast(CurStmt)->getBody(), false); @@ -1509,12 +1525,29 @@ static bool CheckOpenMPLoop(OpenMPDirectiveKind DKind, unsigned NestedLoopCount, return false; } +namespace { +struct OMPCollapseClauseFilter { + OMPCollapseClauseFilter() {} + bool operator()(const OMPClause *C) { + return C->getClauseKind() == OMPC_collapse; + } +}; +} // namespace + +static Expr *GetCollapseNumberExpr(ArrayRef Clauses) { + OMPExecutableDirective::filtered_clause_iterator I( + Clauses); + if (I) + return cast(*I)->getNumForLoops(); + return nullptr; +} + StmtResult Sema::ActOnOpenMPSimdDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { // In presence of clause 'collapse', it will define the nested loops number. - // For now, pass default value of 1. - if (CheckOpenMPLoop(OMPD_simd, 1, AStmt, *this, *DSAStack)) + if (CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), + AStmt, *this, *DSAStack)) return StmtError(); getCurFunction()->setHasBranchProtectedScope(); @@ -1525,8 +1558,8 @@ StmtResult Sema::ActOnOpenMPForDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { // In presence of clause 'collapse', it will define the nested loops number. - // For now, pass default value of 1. - if (CheckOpenMPLoop(OMPD_for, 1, AStmt, *this, *DSAStack)) + if (CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), + AStmt, *this, *DSAStack)) return StmtError(); getCurFunction()->setHasBranchProtectedScope(); diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp index 838eb4e923..8802237b25 100644 --- a/test/OpenMP/for_ast_print.cpp +++ b/test/OpenMP/for_ast_print.cpp @@ -23,11 +23,17 @@ T tmain(T argc) { #pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered nowait for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) - foo(); + for (int j = 0; j < 10; ++j) + for (int j = 0; j < 10; ++j) + for (int j = 0; j < 10; ++j) + foo(); // CHECK-NEXT: #pragma omp parallel // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered nowait // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) // CHECK-NEXT: foo(); return T(); } diff --git a/test/OpenMP/for_collapse_messages.cpp b/test/OpenMP/for_collapse_messages.cpp index 975c4fa6e7..9e14234e07 100644 --- a/test/OpenMP/for_collapse_messages.cpp +++ b/test/OpenMP/for_collapse_messages.cpp @@ -27,8 +27,8 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for collapse ((ST > 0) ? 1 + ST : 2) - for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}} // expected-error@+3 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}} // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}} // expected-error@+1 2 {{expression is not an integral constant expression}} @@ -43,6 +43,8 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}} return argc; } @@ -53,10 +55,10 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for collapse () // expected-error {{expected expression}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} - for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} - for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} + #pragma omp for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{expression is not an integral constant expression}} @@ -73,6 +75,8 @@ int main(int argc, char **argv) { // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} #pragma omp for collapse(collapse(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); + #pragma omp for collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); } diff --git a/test/OpenMP/for_misc_messages.c b/test/OpenMP/for_misc_messages.c index 9b3f290d0e..854898c044 100644 --- a/test/OpenMP/for_misc_messages.c +++ b/test/OpenMP/for_misc_messages.c @@ -119,38 +119,39 @@ void test_collapse() { ; #pragma omp parallel // expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp for collapse(4 for (i = 0; i < 16; ++i) - ; + ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp parallel // expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp for collapse(4, for (i = 0; i < 16; ++i) - ; + ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp parallel // expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp for collapse(4, ) for (i = 0; i < 16; ++i) - ; + ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp parallel +// expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp for collapse(4) for (i = 0; i < 16; ++i) - ; + ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp parallel // expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp for collapse(4 4) for (i = 0; i < 16; ++i) - ; + ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp parallel // expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp for collapse(4, , 4) for (i = 0; i < 16; ++i) - ; + ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp parallel #pragma omp for collapse(4) for (int i1 = 0; i1 < 16; ++i1) @@ -160,10 +161,10 @@ void test_collapse() { foo(); #pragma omp parallel // expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp for collapse(4, 8) for (i = 0; i < 16; ++i) - ; + ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp parallel // expected-error@+1 {{expression is not an integer constant expression}} #pragma omp for collapse(2.5) diff --git a/test/OpenMP/simd_collapse_messages.cpp b/test/OpenMP/simd_collapse_messages.cpp index eea9596ac3..56523b3372 100644 --- a/test/OpenMP/simd_collapse_messages.cpp +++ b/test/OpenMP/simd_collapse_messages.cpp @@ -27,8 +27,8 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp simd collapse ((ST > 0) ? 1 + ST : 2) - for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp simd', but found only 1}} // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}} // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}} // expected-error@+1 2 {{expression is not an integral constant expression}} @@ -43,6 +43,8 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp simd'}} return argc; } @@ -53,10 +55,10 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp simd collapse () // expected-error {{expected expression}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} - for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} - for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} + #pragma omp simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} #pragma omp simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{expression is not an integral constant expression}} @@ -69,6 +71,8 @@ int main(int argc, char **argv) { // expected-error@+1 {{expression is not an integral constant expression}} #pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp simd'}} // expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} #pragma omp simd collapse(collapse(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} diff --git a/test/OpenMP/simd_misc_messages.c b/test/OpenMP/simd_misc_messages.c index 20c14f6fc2..4a41bffbda 100644 --- a/test/OpenMP/simd_misc_messages.c +++ b/test/OpenMP/simd_misc_messages.c @@ -169,28 +169,28 @@ void test_collapse() #pragma omp simd collapse 4) for (i = 0; i < 16; ++i) ; // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} + // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp simd collapse(4 - for (i = 0; i < 16; ++i) ; + for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} + // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp simd collapse(4, - for (i = 0; i < 16; ++i) ; + for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} + // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp simd collapse(4,) - for (i = 0; i < 16; ++i) ; - // xxpected-error@+1 {{expected expression}} + for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} + // xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp simd collapse(4) - for (i = 0; i < 16; ++i) ; + for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} + // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp simd collapse(4 4) - for (i = 0; i < 16; ++i) ; + for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} + // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp simd collapse(4,,4) - for (i = 0; i < 16; ++i) ; + for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} #pragma omp simd collapse(4) for (int i1 = 0; i1 < 16; ++i1) for (int i2 = 0; i2 < 16; ++i2) @@ -198,9 +198,9 @@ void test_collapse() for (int i4 = 0; i4 < 16; ++i4) foo(); // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} + // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp simd collapse(4,8) - for (i = 0; i < 16; ++i) ; + for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} // expected-error@+1 {{expression is not an integer constant expression}} #pragma omp simd collapse(2.5) for (i = 0; i < 16; ++i); -- 2.40.0