diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index f0dddf729309f..b9c4389ddd633 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -1882,7 +1882,7 @@ class OMPSeqCstClause : public OMPClause { /// #pragma omp flush acq_rel /// \endcode /// In this example directive '#pragma omp flush' has 'acq_rel' clause. -class OMPAcqRelClause : public OMPClause { +class OMPAcqRelClause final : public OMPClause { public: /// Build 'ack_rel' clause. /// @@ -1915,6 +1915,46 @@ class OMPAcqRelClause : public OMPClause { } }; +/// This represents 'acquire' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush acquire +/// \endcode +/// In this example directive '#pragma omp flush' has 'acquire' clause. +class OMPAcquireClause final : public OMPClause { +public: + /// Build 'acquire' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_acquire, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPAcquireClause() + : OMPClause(OMPC_acquire, SourceLocation(), SourceLocation()) {} + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_acquire; + } +}; + /// This represents clause 'private' in the '#pragma omp ...' directives. /// /// \code diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index d8e6fb6e0254c..916fac717dd44 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3126,6 +3126,11 @@ bool RecursiveASTVisitor::VisitOMPAcqRelClause(OMPAcqRelClause *) { return true; } +template +bool RecursiveASTVisitor::VisitOMPAcquireClause(OMPAcquireClause *) { + return true; +} + template bool RecursiveASTVisitor::VisitOMPThreadsClause(OMPThreadsClause *) { return true; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5cfd32c57c617..cc983f7507110 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9695,9 +9695,9 @@ def note_omp_atomic_capture: Note< "%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">; def err_omp_atomic_several_clauses : Error< "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">; -def err_omp_atomic_several_mem_order_clauses : Error< - "directive '#pragma omp atomic' cannot contain more than one 'seq_cst' or 'acq_rel' clause">; -def note_omp_atomic_previous_clause : Note< +def err_omp_several_mem_order_clauses : Error< + "directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', |}1'acq_rel' or 'acquire' clause">; +def note_omp_previous_mem_order_clause : Note< "'%0' clause used here">; def err_omp_target_contains_not_only_teams : Error< "target construct with nested teams region contains statements outside of the teams construct">; diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 0d7d952a49d6d..346c0f54971df 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -258,6 +258,7 @@ OPENMP_CLAUSE(update, OMPUpdateClause) OPENMP_CLAUSE(capture, OMPCaptureClause) OPENMP_CLAUSE(seq_cst, OMPSeqCstClause) OPENMP_CLAUSE(acq_rel, OMPAcqRelClause) +OPENMP_CLAUSE(acquire, OMPAcquireClause) OPENMP_CLAUSE(depend, OMPDependClause) OPENMP_CLAUSE(device, OMPDeviceClause) OPENMP_CLAUSE(threads, OMPThreadsClause) @@ -491,6 +492,7 @@ OPENMP_ATOMIC_CLAUSE(update) OPENMP_ATOMIC_CLAUSE(capture) OPENMP_ATOMIC_CLAUSE(seq_cst) OPENMP_ATOMIC_CLAUSE(acq_rel) +OPENMP_ATOMIC_CLAUSE(acquire) // Clauses allowed for OpenMP directive 'target'. OPENMP_TARGET_CLAUSE(if) @@ -1089,6 +1091,7 @@ OPENMP_ORDER_KIND(concurrent) // Clauses allowed for OpenMP directive 'flush'. OPENMP_FLUSH_CLAUSE(acq_rel) +OPENMP_FLUSH_CLAUSE(acquire) #undef OPENMP_FLUSH_CLAUSE #undef OPENMP_ORDER_KIND diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d664e4822e142..beaeccd89820c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10331,6 +10331,9 @@ class Sema final { /// Called on well-formed 'acq_rel' clause. OMPClause *ActOnOpenMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed 'acquire' clause. + OMPClause *ActOnOpenMPAcquireClause(SourceLocation StartLoc, + SourceLocation EndLoc); /// Called on well-formed 'threads' clause. OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc); diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index b1f9ad17f708b..b9156e89173bf 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -117,6 +117,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -192,6 +193,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_depend: case OMPC_device: case OMPC_threads: @@ -1340,6 +1342,10 @@ void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) { OS << "acq_rel"; } +void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) { + OS << "acquire"; +} + void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) { OS << "threads"; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index a39bc9af3b03a..abe988b80e7b9 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -19,6 +19,7 @@ #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" #include "clang/AST/ODRHash.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/StmtVisitor.h" #include "llvm/ADT/FoldingSet.h" using namespace clang; @@ -519,6 +520,8 @@ void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {} void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {} +void OMPClauseProfiler::VisitOMPAcquireClause(const OMPAcquireClause *) {} + void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {} void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {} diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 8937e879af2b8..18d97cda71e3a 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -215,6 +215,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_device: case OMPC_threads: case OMPC_simd: @@ -428,6 +429,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_device: case OMPC_threads: case OMPC_simd: @@ -593,7 +595,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, } break; case OMPD_atomic: - if (OpenMPVersion < 50 && CKind == OMPC_acq_rel) + if (OpenMPVersion < 50 && (CKind == OMPC_acq_rel || CKind == OMPC_acquire)) return false; switch (CKind) { #define OPENMP_ATOMIC_CLAUSE(Name) \ diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index cd5bbbbf7c05e..433506ff58181 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -4492,6 +4492,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_default: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_shared: case OMPC_linear: case OMPC_aligned: @@ -4543,11 +4544,14 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { AO = llvm::AtomicOrdering::SequentiallyConsistent; else if (S.getSingleClause()) AO = llvm::AtomicOrdering::AcquireRelease; + else if (S.getSingleClause()) + AO = llvm::AtomicOrdering::Acquire; OpenMPClauseKind Kind = OMPC_unknown; for (const OMPClause *C : S.clauses()) { - // Find first clause (skip seq_cst|acq_rel clause, if it is first). + // Find first clause (skip seq_cst|acq_rel|aqcuire clause, if it is first). if (C->getClauseKind() != OMPC_seq_cst && - C->getClauseKind() != OMPC_acq_rel) { + C->getClauseKind() != OMPC_acq_rel && + C->getClauseKind() != OMPC_acquire) { Kind = C->getClauseKind(); break; } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 8ac0471b18066..0214a6afa9098 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -2090,7 +2090,7 @@ bool Parser::ParseOpenMPSimpleVarList( /// nogroup-clause | num_tasks-clause | hint-clause | to-clause | /// from-clause | is_device_ptr-clause | task_reduction-clause | /// in_reduction-clause | allocator-clause | allocate-clause | -/// acq_rel-clause +/// acq_rel-clause | acquire-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -2200,6 +2200,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_threads: case OMPC_simd: case OMPC_nogroup: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index aa619710c4ef2..ed2320c8ab426 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4988,6 +4988,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -8571,6 +8572,24 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef Clauses, else OrderClause = C; } + OpenMPClauseKind MemOrderKind = OMPC_unknown; + SourceLocation MemOrderLoc; + for (const OMPClause *C : Clauses) { + if (C->getClauseKind() == OMPC_seq_cst || + C->getClauseKind() == OMPC_acq_rel || + C->getClauseKind() == OMPC_acquire) { + if (MemOrderKind != OMPC_unknown) { + Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) + << getOpenMPDirectiveName(OMPD_flush) << 1 + << SourceRange(C->getBeginLoc(), C->getEndLoc()); + Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) + << getOpenMPClauseName(MemOrderKind); + } else { + MemOrderKind = C->getClauseKind(); + MemOrderLoc = C->getBeginLoc(); + } + } + } if (FC && OrderClause) { Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) << getOpenMPClauseName(OrderClause->getClauseKind()); @@ -8925,7 +8944,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, if (AtomicKind != OMPC_unknown) { Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) << SourceRange(C->getBeginLoc(), C->getEndLoc()); - Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) + Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) << getOpenMPClauseName(AtomicKind); } else { AtomicKind = C->getClauseKind(); @@ -8933,11 +8952,13 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, } } if (C->getClauseKind() == OMPC_seq_cst || - C->getClauseKind() == OMPC_acq_rel) { + C->getClauseKind() == OMPC_acq_rel || + C->getClauseKind() == OMPC_acquire) { if (MemOrderKind != OMPC_unknown) { - Diag(C->getBeginLoc(), diag::err_omp_atomic_several_mem_order_clauses) + Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) + << getOpenMPDirectiveName(OMPD_atomic) << 0 << SourceRange(C->getBeginLoc(), C->getEndLoc()); - Diag(MemOrderLoc, diag::note_omp_atomic_previous_clause) + Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) << getOpenMPClauseName(MemOrderKind); } else { MemOrderKind = C->getClauseKind(); @@ -10871,6 +10892,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -11584,6 +11606,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -12007,6 +12030,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_depend: case OMPC_device: case OMPC_threads: @@ -12208,6 +12232,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_depend: case OMPC_device: case OMPC_threads: @@ -12384,6 +12409,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_acq_rel: Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); break; + case OMPC_acquire: + Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); + break; case OMPC_threads: Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); break; @@ -12502,6 +12530,11 @@ OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, return new (Context) OMPAcqRelClause(StartLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPAcquireClause(StartLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) { return new (Context) OMPThreadsClause(StartLoc, EndLoc); @@ -12659,6 +12692,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_capture: case OMPC_seq_cst: case OMPC_acq_rel: + case OMPC_acquire: case OMPC_device: case OMPC_threads: case OMPC_simd: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index bd0df005f60b4..28ff3fdfc41c7 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8811,6 +8811,13 @@ TreeTransform::TransformOMPAcqRelClause(OMPAcqRelClause *C) { return C; } +template +OMPClause * +TreeTransform::TransformOMPAcquireClause(OMPAcquireClause *C) { + // No need to rebuild this clause, no template-dependent parameters. + return C; +} + template OMPClause * TreeTransform::TransformOMPThreadsClause(OMPThreadsClause *C) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index c25ce49423163..89b8e314e8f81 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11669,6 +11669,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_acq_rel: C = new (Context) OMPAcqRelClause(); break; + case OMPC_acquire: + C = new (Context) OMPAcquireClause(); + break; case OMPC_threads: C = new (Context) OMPThreadsClause(); break; @@ -11933,6 +11936,8 @@ void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {} void OMPClauseReader::VisitOMPAcqRelClause(OMPAcqRelClause *) {} +void OMPClauseReader::VisitOMPAcquireClause(OMPAcquireClause *) {} + void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {} void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {} diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 2e19d735265c5..7263e65b47925 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6149,6 +6149,8 @@ void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {} void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {} +void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {} + void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {} void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {} diff --git a/clang/test/OpenMP/atomic_ast_print.cpp b/clang/test/OpenMP/atomic_ast_print.cpp index 06c1aea19691b..1cc4289d42f48 100644 --- a/clang/test/OpenMP/atomic_ast_print.cpp +++ b/clang/test/OpenMP/atomic_ast_print.cpp @@ -59,6 +59,21 @@ T foo(T argc) { a = b; b++; } +#pragma omp atomic acquire + a++; +#pragma omp atomic read acquire + a = argc; +#pragma omp atomic acquire write + a = argc + argc; +#pragma omp atomic update acquire + a = a + argc; +#pragma omp atomic acquire capture + a = b++; +#pragma omp atomic capture acquire + { + a = b; + b++; + } return T(); } @@ -108,6 +123,21 @@ T foo(T argc) { // CHECK-NEXT: a = b; // CHECK-NEXT: b++; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp atomic acquire +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read acquire +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic acquire write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update acquire +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic acquire capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture acquire +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } // CHECK: int a = int(); // CHECK-NEXT: #pragma omp atomic // CHECK-NEXT: a++; @@ -154,6 +184,21 @@ T foo(T argc) { // CHECK-NEXT: a = b; // CHECK-NEXT: b++; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp atomic acquire +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read acquire +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic acquire write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update acquire +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic acquire capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture acquire +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } int main(int argc, char **argv) { int b = 0; @@ -204,6 +249,21 @@ int main(int argc, char **argv) { a = b; b++; } +#pragma omp atomic acquire + a++; +#pragma omp atomic read acquire + a = argc; +#pragma omp atomic acquire write + a = argc + argc; +#pragma omp atomic update acquire + a = a + argc; +#pragma omp atomic acquire capture + a = b++; +#pragma omp atomic capture acquire + { + a = b; + b++; + } // CHECK-NEXT: #pragma omp atomic // CHECK-NEXT: a++; // CHECK-NEXT: #pragma omp atomic read @@ -249,6 +309,21 @@ int main(int argc, char **argv) { // CHECK-NEXT: a = b; // CHECK-NEXT: b++; // CHECK-NEXT: } + // CHECK-NEXT: #pragma omp atomic acquire + // CHECK-NEXT: a++; + // CHECK-NEXT: #pragma omp atomic read acquire + // CHECK-NEXT: a = argc; + // CHECK-NEXT: #pragma omp atomic acquire write + // CHECK-NEXT: a = argc + argc; + // CHECK-NEXT: #pragma omp atomic update acquire + // CHECK-NEXT: a = a + argc; + // CHECK-NEXT: #pragma omp atomic acquire capture + // CHECK-NEXT: a = b++; + // CHECK-NEXT: #pragma omp atomic capture acquire + // CHECK-NEXT: { + // CHECK-NEXT: a = b; + // CHECK-NEXT: b++; + // CHECK-NEXT: } return foo(a); } diff --git a/clang/test/OpenMP/atomic_capture_codegen.cpp b/clang/test/OpenMP/atomic_capture_codegen.cpp index 338ee7dd943fa..d3d4e0800ec27 100644 --- a/clang/test/OpenMP/atomic_capture_codegen.cpp +++ b/clang/test/OpenMP/atomic_capture_codegen.cpp @@ -906,7 +906,7 @@ int main() { #pragma omp atomic capture {bfx4.b /= ldv; iv = bfx4.b;} // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} -// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic +// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) acquire // CHECK: br label %[[CONT:.+]] // CHECK: [[CONT]] // CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] @@ -928,14 +928,15 @@ int main() { // CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]] // CHECK: store i8 %{{.+}}, i8* [[BITCAST1]] // CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[BITCAST1]] -// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] acquire acquire // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] // CHECK: [[EXIT]] // CHECK: [[NEW_VAL_I32:%.+]] = trunc i64 [[NEW_VAL]] to i32 // CHECK: store i32 [[NEW_VAL_I32]], i32* @{{.+}}, -#pragma omp atomic capture +// CHECK: call{{.*}} @__kmpc_flush( +#pragma omp atomic capture acquire iv = bfx4_packed.b += ldv; // CHECK: load i64, i64* // CHECK: [[EXPR:%.+]] = uitofp i64 %{{.+}} to float diff --git a/clang/test/OpenMP/atomic_messages.cpp b/clang/test/OpenMP/atomic_messages.cpp index 804375a852e57..9489eb13fc10e 100644 --- a/clang/test/OpenMP/atomic_messages.cpp +++ b/clang/test/OpenMP/atomic_messages.cpp @@ -733,7 +733,7 @@ T acq_rel() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} ; -// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' or 'acq_rel' clause}} omp50-note@+1 2 {{'acq_rel' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} +// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 2 {{'acq_rel' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} #pragma omp atomic acq_rel seq_cst a += b; @@ -754,7 +754,7 @@ int acq_rel() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} ; -// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' or 'acq_rel' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} +// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} #pragma omp atomic seq_cst acq_rel a += b; @@ -767,6 +767,48 @@ int acq_rel() { return acq_rel(); // omp50-note {{in instantiation of function template specialization 'acq_rel' requested here}} } +template +T acquire() { + T a = 0, b = 0; +// omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +#pragma omp atomic acquire + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 2 {{'acquire' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +#pragma omp atomic acquire seq_cst + a += b; + +// omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +#pragma omp atomic update acquire + // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; + + return T(); +} + +int acquire() { + int a = 0, b = 0; +// Test for atomic acquire +// omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +#pragma omp atomic acquire + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +#pragma omp atomic seq_cst acquire + a += b; + +// omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +#pragma omp atomic update acquire + // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; + + return acquire(); // omp50-note {{in instantiation of function template specialization 'acquire' requested here}} +} + template T mixed() { T a, b = T(); diff --git a/clang/test/OpenMP/atomic_read_codegen.c b/clang/test/OpenMP/atomic_read_codegen.c index 03737b91397f1..713f370a10124 100644 --- a/clang/test/OpenMP/atomic_read_codegen.c +++ b/clang/test/OpenMP/atomic_read_codegen.c @@ -314,13 +314,14 @@ int main() { // CHECK: store x86_fp80 #pragma omp atomic read ldv = bfx4.b; -// CHECK: [[LD:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) monotonic +// CHECK: [[LD:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) acquire // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]] // CHECK: [[LD:%.+]] = load i8, i8* [[LDTEMP]] // CHECK: [[ASHR:%.+]] = ashr i8 [[LD]], 1 // CHECK: sext i8 [[ASHR]] to i64 +// CHECK: call{{.*}} @__kmpc_flush( // CHECK: store x86_fp80 -#pragma omp atomic read +#pragma omp atomic read acquire ldv = bfx4_packed.b; // CHECK: [[LD:%.+]] = load atomic i64, i64* bitcast (<2 x float>* @{{.+}} to i64*) acquire // CHECK: [[BITCAST:%.+]] = bitcast <2 x float>* [[LDTEMP:%.+]] to i64* diff --git a/clang/test/OpenMP/atomic_update_codegen.cpp b/clang/test/OpenMP/atomic_update_codegen.cpp index 6f95c8e84540e..31995f7ae8e90 100644 --- a/clang/test/OpenMP/atomic_update_codegen.cpp +++ b/clang/test/OpenMP/atomic_update_codegen.cpp @@ -811,7 +811,7 @@ int main() { #pragma omp atomic update bfx4_packed.a -= ldv; // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} -// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic +// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) acquire // CHECK: br label %[[CONT:.+]] // CHECK: [[CONT]] // CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] @@ -830,12 +830,12 @@ int main() { // CHECK: [[VAL:%.+]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] // CHECK: store i64 [[VAL]], i64* [[TEMP1]] // CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[TEMP1]] -// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] acquire acquire // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] // CHECK: [[EXIT]] -#pragma omp atomic +#pragma omp atomic acquire bfx4.b /= ldv; // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} // CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) acquire diff --git a/clang/test/OpenMP/atomic_write_codegen.c b/clang/test/OpenMP/atomic_write_codegen.c index 517765ccdf478..c8e8d343252a4 100644 --- a/clang/test/OpenMP/atomic_write_codegen.c +++ b/clang/test/OpenMP/atomic_write_codegen.c @@ -87,8 +87,8 @@ int main() { #pragma omp atomic write __imag(civ) = 1; // CHECK: load i8, i8* -// CHECK: store atomic i8 -#pragma omp atomic write +// CHECK: store atomic i8{{.*}}monotonic +#pragma omp atomic write acquire bx = bv; // CHECK: load i8, i8* // CHECK: store atomic i8 @@ -189,7 +189,7 @@ int main() { #pragma omp atomic write bx = cv; // CHECK: load i8, i8* -// CHECK: store atomic i8 +// CHECK: store atomic i8{{.*}}seq_cst // CHECK: call{{.*}} @__kmpc_flush( #pragma omp atomic write, seq_cst cx = ucv; @@ -470,7 +470,7 @@ int main() { bfx4.b = ldv; // CHECK: load x86_fp80, x86_fp80* @{{.+}} // CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i64 -// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic +// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) acquire // CHECK: br label %[[CONT:.+]] // CHECK: [[CONT]] // CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ] @@ -481,12 +481,12 @@ int main() { // CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]] // CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]] // CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]] -// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] acquire acquire // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] // CHECK: [[EXIT]] -#pragma omp atomic write +#pragma omp atomic write acquire bfx4_packed.b = ldv; // CHECK: load i64, i64* // CHECK: [[VEC_ITEM_VAL:%.+]] = uitofp i64 %{{.+}} to float diff --git a/clang/test/OpenMP/flush_ast_print.cpp b/clang/test/OpenMP/flush_ast_print.cpp index ca275b8e1f594..bfbe8c3c3268b 100644 --- a/clang/test/OpenMP/flush_ast_print.cpp +++ b/clang/test/OpenMP/flush_ast_print.cpp @@ -17,20 +17,24 @@ T tmain(T argc) { static T a; #pragma omp flush #pragma omp flush acq_rel +#pragma omp flush acquire #pragma omp flush(a) return a + argc; } // CHECK: static T a; // CHECK-NEXT: #pragma omp flush{{$}} // CHECK-NEXT: #pragma omp flush acq_rel{{$}} +// CHECK-NEXT: #pragma omp flush acquire{{$}} // CHECK-NEXT: #pragma omp flush (a) // CHECK: static int a; // CHECK-NEXT: #pragma omp flush // CHECK-NEXT: #pragma omp flush acq_rel{{$}} +// CHECK-NEXT: #pragma omp flush acquire{{$}} // CHECK-NEXT: #pragma omp flush (a) // CHECK: static char a; // CHECK-NEXT: #pragma omp flush // CHECK-NEXT: #pragma omp flush acq_rel{{$}} +// CHECK-NEXT: #pragma omp flush acquire{{$}} // CHECK-NEXT: #pragma omp flush (a) int main(int argc, char **argv) { @@ -38,9 +42,11 @@ int main(int argc, char **argv) { // CHECK: static int a; #pragma omp flush #pragma omp flush acq_rel +#pragma omp flush acquire #pragma omp flush(a) // CHECK-NEXT: #pragma omp flush // CHECK-NEXT: #pragma omp flush acq_rel +// CHECK-NEXT: #pragma omp flush acquire{{$}} // CHECK-NEXT: #pragma omp flush (a) return tmain(argc) + tmain(argv[0][0]) + a; } diff --git a/clang/test/OpenMP/flush_codegen.cpp b/clang/test/OpenMP/flush_codegen.cpp index c73741c4d4926..ce66d98ead203 100644 --- a/clang/test/OpenMP/flush_codegen.cpp +++ b/clang/test/OpenMP/flush_codegen.cpp @@ -1,16 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s @@ -23,6 +17,8 @@ template T tmain(T argc) { static T a; #pragma omp flush +#pragma omp flush acq_rel +#pragma omp flush acquire #pragma omp flush(a) return a + argc; } @@ -31,7 +27,11 @@ T tmain(T argc) { int main() { static int a; #pragma omp flush +#pragma omp flush acq_rel +#pragma omp flush acquire #pragma omp flush(a) + // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) + // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) return tmain(a); @@ -42,6 +42,8 @@ int main() { // CHECK: [[TMAIN]] // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) +// CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) +// CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: ret // CHECK-NOT: line: 0, diff --git a/clang/test/OpenMP/flush_messages.cpp b/clang/test/OpenMP/flush_messages.cpp index 234db25f26dcc..9ed08e2ba38e7 100644 --- a/clang/test/OpenMP/flush_messages.cpp +++ b/clang/test/OpenMP/flush_messages.cpp @@ -136,6 +136,8 @@ label1 : { ; #pragma omp flush seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp flush'}} #pragma omp flush acq_rel // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} +#pragma omp flush acquire // omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} +#pragma omp flush acq_rel acquire // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel' or 'acquire' clause}} omp50-note {{'acq_rel' clause used here}} #pragma omp flush acq_rel (argc) // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp50-error {{'flush' directive with memory order clause 'acq_rel' cannot have the list}} omp50-note {{memory order clause 'acq_rel' is specified here}} #pragma omp flush(argc) acq_rel // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp50-error {{'flush' directive with memory order clause 'acq_rel' cannot have the list}} omp50-note {{memory order clause 'acq_rel' is specified here}} return tmain(argc); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 95cb517fa3328..5dc33bd445486 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2236,6 +2236,8 @@ void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {} void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {} +void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {} + void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {} void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}