From 6b8046addfce08aa075f0db860f8a5a29fd6e45f Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 3 Sep 2015 07:23:48 +0000 Subject: [PATCH] [OPENMP 4.1] Parsing/sema analysis for extended format of 'if' clause. OpenMP 4.1 added special 'directive-name-modifier' to the 'if' clause. Format of 'if' clause is as follows: ``` if([ directive-name-modifier :] scalar-logical-expression) ``` The restriction rules are also changed. 1. If any 'if' clause on the directive includes a 'directive-name-modifier' then all 'if' clauses on the directive must include a 'directive-name-modifier'. 2. At most one 'if' clause without a 'directive-name-modifier' can appear on the directive. 3. At most one 'if' clause with some particular 'directive-name-modifier' can appear on the directive. 'directive-name-modifier' is important for combined directives and allows to separate conditions in 'if' clause for simple sub-directives in combined directive. This 'directive-name-modifier' identifies the sub-directive to which this 'if' clause must be applied. llvm-svn: 246747 --- clang/include/clang/AST/OpenMPClause.h | 46 +++- .../clang/Basic/DiagnosticCommonKinds.td | 3 + .../clang/Basic/DiagnosticParseKinds.td | 2 - .../clang/Basic/DiagnosticSemaKinds.td | 8 + clang/include/clang/Sema/Sema.h | 7 +- clang/lib/AST/StmtPrinter.cpp | 2 + clang/lib/Parse/ParseOpenMP.cpp | 99 +++++---- clang/lib/Sema/SemaOpenMP.cpp | 208 +++++++++++++++--- clang/lib/Sema/TreeTransform.h | 16 +- clang/lib/Serialization/ASTReaderStmt.cpp | 3 + clang/lib/Serialization/ASTWriterStmt.cpp | 3 + clang/test/OpenMP/for_schedule_messages.cpp | 6 +- .../OpenMP/for_simd_schedule_messages.cpp | 6 +- .../test/OpenMP/parallel_for_if_messages.cpp | 28 +++ .../OpenMP/parallel_for_schedule_messages.cpp | 6 +- .../OpenMP/parallel_for_simd_if_messages.cpp | 28 +++ .../parallel_for_simd_schedule_messages.cpp | 6 +- clang/test/OpenMP/parallel_if_messages.cpp | 14 ++ .../OpenMP/parallel_sections_if_messages.cpp | 48 ++++ clang/test/OpenMP/target_data_if_messages.cpp | 6 + clang/test/OpenMP/target_if_messages.cpp | 12 + clang/test/OpenMP/task_if_messages.cpp | 12 + 22 files changed, 470 insertions(+), 99 deletions(-) diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 40ac7fa51363..fee0befb5b85 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -152,10 +152,10 @@ public: /// \brief This represents 'if' clause in the '#pragma omp ...' directive. /// /// \code -/// #pragma omp parallel if(a > 5) +/// #pragma omp parallel if(parallel:a > 5) /// \endcode -/// In this example directive '#pragma omp parallel' has simple 'if' -/// clause with condition 'a > 5'. +/// In this example directive '#pragma omp parallel' has simple 'if' clause with +/// condition 'a > 5' and directive name modifier 'parallel'. /// class OMPIfClause : public OMPClause { friend class OMPClauseReader; @@ -163,37 +163,67 @@ class OMPIfClause : public OMPClause { SourceLocation LParenLoc; /// \brief Condition of the 'if' clause. Stmt *Condition; + /// \brief Location of ':' (if any). + SourceLocation ColonLoc; + /// \brief Directive name modifier for the clause. + OpenMPDirectiveKind NameModifier; + /// \brief Name modifier location. + SourceLocation NameModifierLoc; /// \brief Set condition. /// void setCondition(Expr *Cond) { Condition = Cond; } + /// \brief Set directive name modifier for the clause. + /// + void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; } + /// \brief Set location of directive name modifier for the clause. + /// + void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; } + /// \brief Set location of ':'. + /// + void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } public: /// \brief Build 'if' clause with condition \a Cond. /// + /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause. + /// \param Cond Condition of the clause. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. - /// \param Cond Condition of the clause. + /// \param NameModifierLoc Location of directive name modifier. + /// \param ColonLoc [OpenMP 4.1] Location of ':'. /// \param EndLoc Ending location of the clause. /// - OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc, + OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc), - Condition(Cond) {} + Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier), + NameModifierLoc(NameModifierLoc) {} /// \brief Build an empty clause. /// OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Condition(nullptr) {} + : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(), + Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown), + NameModifierLoc() {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } + /// \brief Return the location of ':'. + SourceLocation getColonLoc() const { return ColonLoc; } + /// \brief Returns condition. Expr *getCondition() const { return cast_or_null(Condition); } + /// \brief Return directive name modifier associated with the clause. + OpenMPDirectiveKind getNameModifier() const { return NameModifier; } + + /// \brief Return the location of directive name modifier. + SourceLocation getNameModifierLoc() const { return NameModifierLoc; } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_if; diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index e5c924d886c1..42e761a630bd 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -211,4 +211,7 @@ def note_mt_message : Note<"[rewriter] %0">; def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">; def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">; +// OpenMP +def err_omp_more_one_clause : Error< + "directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier}2">; } diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index ef71225514a4..3f8668130387 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -987,8 +987,6 @@ def err_omp_expected_punc : Error< "expected ',' or ')' in '%0' %select{clause|directive}1">; def err_omp_unexpected_clause : Error< "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">; -def err_omp_more_one_clause : Error< - "directive '#pragma omp %0' cannot contain more than one '%1' clause">; def err_omp_immediate_directive : Error< "'#pragma omp %0' cannot be an immediate substatement">; def err_omp_expected_identifier_for_critical : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1e1ee9b6f5c1..ecf5c2d26049 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7694,6 +7694,14 @@ def err_omp_wrong_linear_modifier_non_reference : Error< "variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">; def err_omp_wrong_simdlen_safelen_values : Error< "the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">; +def err_omp_wrong_if_directive_name_modifier : Error< + "directive name modifier '%0' is not allowed for '#pragma omp %1'">; +def err_omp_no_more_if_clause : Error< + "no more 'if' clause is allowed">; +def err_omp_unnamed_if_clause : Error< + "expected %select{|one of}0 %1 directive name modifier%select{|s}0">; +def note_omp_previous_named_if_clause : Note< + "previous clause with directive name modifier specified here">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 77cc667ab288..e9365e8766b8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7889,8 +7889,11 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'if' clause. - OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, + OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, + Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation NameModifierLoc, + SourceLocation ColonLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'final' clause. OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, @@ -7945,7 +7948,7 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ArgumentLoc, - SourceLocation CommaLoc, + SourceLocation DelimLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'schedule' clause. OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 8470a0c5a140..f08e3a3a9b13 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -602,6 +602,8 @@ public: void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) { OS << "if("; + if (Node->getNameModifier() != OMPD_unknown) + OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": "; Node->getCondition()->printPretty(OS, nullptr, Policy, 0); OS << ")"; } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index ed71917dbcb4..6c9c88a49c2d 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -288,7 +288,6 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { ConsumeToken(); StmtResult AssociatedStmt; - bool CreateDirective = true; if (HasAssociatedStatement) { // The body is a block scope like in Lambdas and Blocks. Sema::CompoundScopeRAII CompoundScope(Actions); @@ -298,12 +297,10 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { AssociatedStmt = ParseStatement(); Actions.ActOnFinishOfCompoundStmt(); AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses); - CreateDirective = AssociatedStmt.isUsable(); } - if (CreateDirective) - Directive = Actions.ActOnOpenMPExecutableDirective( - DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, - EndLoc); + Directive = Actions.ActOnOpenMPExecutableDirective( + DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, + EndLoc); // Exit scope. Actions.EndOpenMPDSABlock(Directive.get()); @@ -411,7 +408,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, } switch (CKind) { - case OMPC_if: case OMPC_final: case OMPC_num_threads: case OMPC_safelen: @@ -420,7 +416,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_ordered: case OMPC_device: // OpenMP [2.5, Restrictions] - // At most one if clause can appear on the directive. // At most one num_threads clause can appear on the directive. // OpenMP [2.8.1, simd construct, Restrictions] // Only one safelen clause can appear on a simd directive. @@ -432,8 +427,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // At most one if clause can appear on the directive. // At most one final clause can appear on the directive. if (!FirstClause) { - Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind) - << getOpenMPClauseName(CKind); + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -450,8 +445,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // OpenMP [2.5, parallel Construct, Restrictions] // At most one proc_bind clause can appear on the directive. if (!FirstClause) { - Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind) - << getOpenMPClauseName(CKind); + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -461,11 +456,12 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // OpenMP [2.7.1, Restrictions, p. 3] // Only one schedule clause can appear on a loop directive. if (!FirstClause) { - Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind) - << getOpenMPClauseName(CKind); + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } + case OMPC_if: Clause = ParseOpenMPSingleExprWithArgClause(CKind); break; case OMPC_nowait: @@ -481,8 +477,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // OpenMP [2.7.1, Restrictions, C/C++, p. 4] // Only one nowait clause can appear on a for directive. if (!FirstClause) { - Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind) - << getOpenMPClauseName(CKind); + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -515,12 +511,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, return ErrorFound ? nullptr : Clause; } -/// \brief Parsing of OpenMP clauses with single expressions like 'if', -/// 'final', 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', -/// 'thread_limit' or 'simdlen'. -/// -/// if-clause: -/// 'if' '(' expression ')' +/// \brief Parsing of OpenMP clauses with single expressions like 'final', +/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 'thread_limit' +/// or 'simdlen'. /// /// final-clause: /// 'final' '(' expression ')' @@ -545,8 +538,10 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) { getOpenMPClauseName(Kind))) return nullptr; + SourceLocation ELoc = Tok.getLocation(); ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); // Parse ')'. T.consumeClose(); @@ -620,9 +615,12 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) { /// schedule-clause: /// 'schedule' '(' kind [',' expression ] ')' /// +/// if-clause: +/// 'if' '(' [ directive-name-modifier ':' ] expression ')' +/// OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) { SourceLocation Loc = ConsumeToken(); - SourceLocation CommaLoc; + SourceLocation DelimLoc; // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, @@ -630,29 +628,50 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) { return nullptr; ExprResult Val; - unsigned Type = getOpenMPSimpleClauseType( - Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); - SourceLocation KLoc = Tok.getLocation(); - if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && - Tok.isNot(tok::annot_pragma_openmp_end)) - ConsumeAnyToken(); + unsigned Arg; + SourceLocation KLoc; + if (Kind == OMPC_schedule) { + Arg = getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); + KLoc = Tok.getLocation(); + if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && + Tok.isNot(tok::annot_pragma_openmp_end)) + ConsumeAnyToken(); + if ((Arg == OMPC_SCHEDULE_static || Arg == OMPC_SCHEDULE_dynamic || + Arg == OMPC_SCHEDULE_guided) && + Tok.is(tok::comma)) + DelimLoc = ConsumeAnyToken(); + } else { + assert(Kind == OMPC_if); + KLoc = Tok.getLocation(); + Arg = ParseOpenMPDirectiveKind(*this); + if (Arg != OMPD_unknown) { + ConsumeToken(); + if (Tok.is(tok::colon)) + DelimLoc = ConsumeToken(); + else + Diag(Tok, diag::warn_pragma_expected_colon) + << "directive name modifier"; + } + } - if (Kind == OMPC_schedule && - (Type == OMPC_SCHEDULE_static || Type == OMPC_SCHEDULE_dynamic || - Type == OMPC_SCHEDULE_guided) && - Tok.is(tok::comma)) { - CommaLoc = ConsumeAnyToken(); + bool NeedAnExpression = + (Kind == OMPC_schedule && DelimLoc.isValid()) || Kind == OMPC_if; + if (NeedAnExpression) { + SourceLocation ELoc = Tok.getLocation(); ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional); - if (Val.isInvalid()) - return nullptr; + Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); } // Parse ')'. T.consumeClose(); + if (NeedAnExpression && Val.isInvalid()) + return nullptr; + return Actions.ActOnOpenMPSingleExprWithArgClause( - Kind, Type, Val.get(), Loc, T.getOpenLocation(), KLoc, CommaLoc, + Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, T.getCloseLocation()); } @@ -838,9 +857,9 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon); if (MustHaveTail) { ColonLoc = Tok.getLocation(); - ConsumeToken(); - ExprResult Tail = - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + SourceLocation ELoc = ConsumeToken(); + ExprResult Tail = ParseAssignmentExpression(); + Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc); if (Tail.isUsable()) TailExpr = Tail.get(); else diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ea31260cc7a4..b4a6768394bd 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1985,6 +1985,82 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, return false; } +static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, + ArrayRef Clauses, + ArrayRef AllowedNameModifiers) { + bool ErrorFound = false; + unsigned NamedModifiersNumber = 0; + SmallVector FoundNameModifiers( + OMPD_unknown + 1); + for (const auto *C : Clauses) { + if (const auto *IC = dyn_cast_or_null(C)) { + // At most one if clause without a directive-name-modifier can appear on + // the directive. + OpenMPDirectiveKind CurNM = IC->getNameModifier(); + if (FoundNameModifiers[CurNM]) { + S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) + << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); + ErrorFound = true; + } else if (CurNM != OMPD_unknown) + ++NamedModifiersNumber; + FoundNameModifiers[CurNM] = IC; + if (CurNM == OMPD_unknown) + continue; + // Check if the specified name modifier is allowed for the current + // directive. + // At most one if clause with the particular directive-name-modifier can + // appear on the directive. + bool MatchFound = false; + for (auto NM : AllowedNameModifiers) { + if (CurNM == NM) { + MatchFound = true; + break; + } + } + if (!MatchFound) { + S.Diag(IC->getNameModifierLoc(), + diag::err_omp_wrong_if_directive_name_modifier) + << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); + ErrorFound = true; + } + } + } + // If any if clause on the directive includes a directive-name-modifier then + // all if clauses on the directive must include a directive-name-modifier. + if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { + if (NamedModifiersNumber == AllowedNameModifiers.size()) { + S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), + diag::err_omp_no_more_if_clause); + } else { + std::string Values; + std::string Sep(", "); + unsigned AllowedCnt = 0; + unsigned TotalAllowedNum = + AllowedNameModifiers.size() - NamedModifiersNumber; + for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; + ++Cnt) { + OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; + if (!FoundNameModifiers[NM]) { + Values += "'"; + Values += getOpenMPDirectiveName(NM); + Values += "'"; + if (AllowedCnt + 2 == TotalAllowedNum) + Values += " or "; + else if (AllowedCnt + 1 != TotalAllowedNum) + Values += Sep; + ++AllowedCnt; + } + } + S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), + diag::err_omp_unnamed_if_clause) + << (TotalAllowedNum > 1) << Values; + } + ErrorFound = true; + } + return ErrorFound; +} + StmtResult Sema::ActOnOpenMPExecutableDirective( OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef Clauses, @@ -2021,10 +2097,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( } } + llvm::SmallVector AllowedNameModifiers; switch (Kind) { case OMPD_parallel: Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_simd: Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, @@ -2064,18 +2142,22 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_parallel_for: Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_parallel_for_simd: Res = ActOnOpenMPParallelForSimdDirective( ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_parallel_sections: Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_task: Res = ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_task); break; case OMPD_taskyield: assert(ClausesWithImplicit.empty() && @@ -2124,6 +2206,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_target: Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_target); break; case OMPD_cancellation_point: assert(ClausesWithImplicit.empty() && @@ -2142,6 +2225,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_target_data: Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_target_data); break; case OMPD_threadprivate: llvm_unreachable("OpenMP Directive is not allowed"); @@ -2153,8 +2237,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) << P.first << P.second->getSourceRange(); } - if (!VarsWithInheritedDSA.empty()) - return StmtError(); + ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; + + if (!AllowedNameModifiers.empty()) + ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || + ErrorFound; if (ErrorFound) return StmtError(); @@ -2165,7 +2252,9 @@ StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3557,6 +3646,10 @@ StmtResult Sema::ActOnOpenMPSimdDirective( ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); OMPLoopDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. @@ -3606,6 +3699,10 @@ StmtResult Sema::ActOnOpenMPForDirective( ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); OMPLoopDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. @@ -3637,6 +3734,10 @@ StmtResult Sema::ActOnOpenMPForSimdDirective( ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); OMPLoopDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. @@ -3687,7 +3788,10 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); auto BaseStmt = AStmt; while (CapturedStmt *CS = dyn_cast_or_null(BaseStmt)) BaseStmt = CS->getCapturedStmt(); @@ -3719,7 +3823,10 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef Clauses, StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3730,7 +3837,10 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3757,7 +3867,10 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef Clauses, StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3768,7 +3881,10 @@ StmtResult Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3780,7 +3896,9 @@ StmtResult Sema::ActOnOpenMPParallelForDirective( ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap &VarsWithImplicitDSA) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3821,7 +3939,9 @@ StmtResult Sema::ActOnOpenMPParallelForSimdDirective( ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap &VarsWithImplicitDSA) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3877,7 +3997,10 @@ StmtResult Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); auto BaseStmt = AStmt; while (CapturedStmt *CS = dyn_cast_or_null(BaseStmt)) BaseStmt = CS->getCapturedStmt(); @@ -3910,7 +4033,9 @@ Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef Clauses, StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3942,7 +4067,10 @@ StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3959,7 +4087,10 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef Clauses, StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -4210,7 +4341,9 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + auto CS = cast(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -4631,7 +4764,10 @@ StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); // OpenMP [2.16, Nesting of Regions] // If specified, a teams construct must be contained within a target @@ -4672,6 +4808,11 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { + if (!AStmt) + return StmtError(); + + assert(isa(AStmt) && "Captured statement expected"); + getCurFunction()->setHasBranchProtectedScope(); return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, @@ -4681,7 +4822,9 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef Clauses, StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -4743,9 +4886,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation EndLoc) { OMPClause *Res = nullptr; switch (Kind) { - case OMPC_if: - Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc); - break; case OMPC_final: Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -4767,6 +4907,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_device: Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); break; + case OMPC_if: case OMPC_default: case OMPC_proc_bind: case OMPC_schedule: @@ -4796,8 +4937,11 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, return Res; } -OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, +OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, + Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation NameModifierLoc, + SourceLocation ColonLoc, SourceLocation EndLoc) { Expr *ValExpr = Condition; if (!Condition->isValueDependent() && !Condition->isTypeDependent() && @@ -4811,7 +4955,8 @@ OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, ValExpr = Val.get(); } - return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc); + return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc, + NameModifierLoc, ColonLoc, EndLoc); } OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, @@ -5129,16 +5274,20 @@ OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ArgumentLoc, SourceLocation CommaLoc, + SourceLocation ArgumentLoc, SourceLocation DelimLoc, SourceLocation EndLoc) { OMPClause *Res = nullptr; switch (Kind) { case OMPC_schedule: Res = ActOnOpenMPScheduleClause( static_cast(Argument), Expr, StartLoc, - LParenLoc, ArgumentLoc, CommaLoc, EndLoc); + LParenLoc, ArgumentLoc, DelimLoc, EndLoc); break; case OMPC_if: + Res = + ActOnOpenMPIfClause(static_cast(Argument), Expr, + StartLoc, LParenLoc, ArgumentLoc, DelimLoc, EndLoc); + break; case OMPC_final: case OMPC_num_threads: case OMPC_safelen: @@ -6382,9 +6531,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause( BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BO_Assign, LHSDRE, ConditionalOp); } - if (ReductionOp.isUsable()) { - ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); - } + ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); } if (ReductionOp.isInvalid()) continue; @@ -6551,6 +6698,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause( buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); ExprResult CalcStep = BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); + CalcStep = ActOnFinishFullExpr(CalcStep.get()); // Warn about zero linear step (it would be probably better specified as // making corresponding variables 'const'). @@ -6607,13 +6755,15 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, ExprResult Update = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, /* Subtract */ false); - Update = SemaRef.ActOnFinishFullExpr(Update.get()); + Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), + /*DiscardedValue=*/true); // Build final: Var = InitExpr + NumIterations * Step ExprResult Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, InitExpr, NumIterations, Step, /* Subtract */ false); - Final = SemaRef.ActOnFinishFullExpr(Final.get()); + Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), + /*DiscardedValue=*/true); if (!Update.isUsable() || !Final.isUsable()) { Updates.push_back(nullptr); Finals.push_back(nullptr); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 692a2f1dcb48..1629138c5b7a 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1355,12 +1355,15 @@ public: /// /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPIfClause(Expr *Condition, - SourceLocation StartLoc, + OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier, + Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation NameModifierLoc, + SourceLocation ColonLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPIfClause(Condition, StartLoc, - LParenLoc, EndLoc); + return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc, + LParenLoc, NameModifierLoc, ColonLoc, + EndLoc); } /// \brief Build a new OpenMP 'final' clause. @@ -7214,8 +7217,9 @@ OMPClause *TreeTransform::TransformOMPIfClause(OMPIfClause *C) { ExprResult Cond = getDerived().TransformExpr(C->getCondition()); if (Cond.isInvalid()) return nullptr; - return getDerived().RebuildOMPIfClause(Cond.get(), C->getLocStart(), - C->getLParenLoc(), C->getLocEnd()); + return getDerived().RebuildOMPIfClause( + C->getNameModifier(), Cond.get(), C->getLocStart(), C->getLParenLoc(), + C->getNameModifierLoc(), C->getColonLoc(), C->getLocEnd()); } template diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 2d6f5e0db7ff..9446db842f39 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1812,6 +1812,9 @@ OMPClause *OMPClauseReader::readClause() { } void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) { + C->setNameModifier(static_cast(Record[Idx++])); + C->setNameModifierLoc(Reader->ReadSourceLocation(Record, Idx)); + C->setColonLoc(Reader->ReadSourceLocation(Record, Idx)); C->setCondition(Reader->Reader.ReadSubExpr()); C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); } diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 2695f67f0576..7db73f5a53bc 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1728,6 +1728,9 @@ void OMPClauseWriter::writeClause(OMPClause *C) { } void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) { + Record.push_back(C->getNameModifier()); + Writer->Writer.AddSourceLocation(C->getNameModifierLoc(), Record); + Writer->Writer.AddSourceLocation(C->getColonLoc(), Record); Writer->Writer.AddStmt(C->getCondition()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); } diff --git a/clang/test/OpenMP/for_schedule_messages.cpp b/clang/test/OpenMP/for_schedule_messages.cpp index c4490e88f02b..807a97968362 100644 --- a/clang/test/OpenMP/for_schedule_messages.cpp +++ b/clang/test/OpenMP/for_schedule_messages.cpp @@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} + #pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -76,14 +76,14 @@ int main(int argc, char **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} + #pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp for schedule (static, 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]; // expected-error@+3 {{statement after '#pragma omp for' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp for schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/clang/test/OpenMP/for_simd_schedule_messages.cpp b/clang/test/OpenMP/for_simd_schedule_messages.cpp index 1367676ad58c..740b40ba3045 100644 --- a/clang/test/OpenMP/for_simd_schedule_messages.cpp +++ b/clang/test/OpenMP/for_simd_schedule_messages.cpp @@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + #pragma omp for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -76,14 +76,14 @@ int main(int argc, char **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + #pragma omp for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp for simd schedule (static, 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]; // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/clang/test/OpenMP/parallel_for_if_messages.cpp b/clang/test/OpenMP/parallel_for_if_messages.cpp index cf2a3b431dc7..555f3713b511 100644 --- a/clang/test/OpenMP/parallel_for_if_messages.cpp +++ b/clang/test/OpenMP/parallel_for_if_messages.cpp @@ -34,6 +34,20 @@ int tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for if(argc) for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} + for (i = 0; i < argc; ++i) foo(); return 0; } @@ -64,6 +78,20 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} + for (i = 0; i < argc; ++i) foo(); return tmain(argc, argv); } diff --git a/clang/test/OpenMP/parallel_for_schedule_messages.cpp b/clang/test/OpenMP/parallel_for_schedule_messages.cpp index c12c4282686b..5ed6dc8883a7 100644 --- a/clang/test/OpenMP/parallel_for_schedule_messages.cpp +++ b/clang/test/OpenMP/parallel_for_schedule_messages.cpp @@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} + #pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -76,14 +76,14 @@ int main(int argc, char **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} + #pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp parallel for schedule (static, 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]; // expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp parallel for schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/clang/test/OpenMP/parallel_for_simd_if_messages.cpp b/clang/test/OpenMP/parallel_for_simd_if_messages.cpp index ca327cff7206..7662d0f5e73a 100644 --- a/clang/test/OpenMP/parallel_for_simd_if_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_if_messages.cpp @@ -34,6 +34,20 @@ int tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd if(argc) for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} + for (i = 0; i < argc; ++i) foo(); return 0; } @@ -64,6 +78,20 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} + for (i = 0; i < argc; ++i) foo(); return tmain(argc, argv); } diff --git a/clang/test/OpenMP/parallel_for_simd_schedule_messages.cpp b/clang/test/OpenMP/parallel_for_simd_schedule_messages.cpp index 36befb213559..43e99ae096d7 100644 --- a/clang/test/OpenMP/parallel_for_simd_schedule_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_schedule_messages.cpp @@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + #pragma omp parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -76,14 +76,14 @@ int main(int argc, char **argv) { // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} #pragma omp parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + #pragma omp parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} #pragma omp parallel for simd schedule (static, 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]; // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp parallel for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/clang/test/OpenMP/parallel_if_messages.cpp b/clang/test/OpenMP/parallel_if_messages.cpp index 97096dfae3e8..bba2861e6471 100644 --- a/clang/test/OpenMP/parallel_if_messages.cpp +++ b/clang/test/OpenMP/parallel_if_messages.cpp @@ -22,6 +22,13 @@ int tmain(T argc, S **argv) { #pragma omp parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if(argc) + #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc) + #pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}} + #pragma omp parallel if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}} + #pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} foo(); return 0; @@ -40,6 +47,13 @@ int main(int argc, char **argv) { #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc) + #pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}} + #pragma omp parallel if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}} + #pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} foo(); return tmain(argc, argv); diff --git a/clang/test/OpenMP/parallel_sections_if_messages.cpp b/clang/test/OpenMP/parallel_sections_if_messages.cpp index 03182b4c8fe1..db4d0a1ec712 100644 --- a/clang/test/OpenMP/parallel_sections_if_messages.cpp +++ b/clang/test/OpenMP/parallel_sections_if_messages.cpp @@ -55,6 +55,30 @@ int tmain(T argc, S **argv) { { foo(); } + #pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} + { + foo(); + } return 0; } @@ -108,6 +132,30 @@ int main(int argc, char **argv) { { foo(); } + #pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} + { + foo(); + } return tmain(argc, argv); } diff --git a/clang/test/OpenMP/target_data_if_messages.cpp b/clang/test/OpenMP/target_data_if_messages.cpp index 3a0e815798ff..38008dd30fe5 100644 --- a/clang/test/OpenMP/target_data_if_messages.cpp +++ b/clang/test/OpenMP/target_data_if_messages.cpp @@ -20,6 +20,12 @@ int main(int argc, char **argv) { #pragma omp target data if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}} #pragma omp target data if (S1) // expected-error {{'S1' does not refer to a value}} #pragma omp target data if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data if(target data : argc) + #pragma omp target data if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}} + #pragma omp target data if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}} + #pragma omp target data if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} foo(); return 0; diff --git a/clang/test/OpenMP/target_if_messages.cpp b/clang/test/OpenMP/target_if_messages.cpp index 5193b64ff720..58a9ba2af891 100644 --- a/clang/test/OpenMP/target_if_messages.cpp +++ b/clang/test/OpenMP/target_if_messages.cpp @@ -22,6 +22,12 @@ int tmain(T argc, S **argv) { #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if(argc) + #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc) + #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}} + #pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}} + #pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} foo(); return 0; @@ -40,6 +46,12 @@ int main(int argc, char **argv) { #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc) + #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}} + #pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}} + #pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} foo(); return tmain(argc, argv); diff --git a/clang/test/OpenMP/task_if_messages.cpp b/clang/test/OpenMP/task_if_messages.cpp index ae6bb13093d9..029e4e1f1b7a 100644 --- a/clang/test/OpenMP/task_if_messages.cpp +++ b/clang/test/OpenMP/task_if_messages.cpp @@ -22,6 +22,12 @@ int tmain(T argc, S **argv) { #pragma omp task if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if(argc) + #pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc) + #pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}} + #pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}} + #pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} foo(); return 0; @@ -40,6 +46,12 @@ int main(int argc, char **argv) { #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc) + #pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}} + #pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}} + #pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} foo(); return tmain(argc, argv);