diff --git a/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst b/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst --- a/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst @@ -51,3 +51,12 @@ // WARNING: OpenMP directive ``parallel`` specifies ``default(shared)`` // clause. Consider using ``default(none)`` clause instead. } + + // ``parallel`` directive can have ``default`` clause, and said clause is + // specified, but with ``firstprivate`` kind, which is not ``none``, diagnose. + void p0_3() { + #pragma omp parallel default(firstprivate) + ; + // WARNING: OpenMP directive ``parallel`` specifies ``default(firstprivate)`` + // clause. Consider using ``default(none)`` clause instead. + } diff --git a/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp b/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp @@ -1,5 +1,5 @@ -// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -fopenmp=libomp -fopenmp-version=40 -// RUN: %check_clang_tidy -std=c11 %s openmp-use-default-none %t -- -- -x c -fopenmp=libomp -fopenmp-version=40 +// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -fopenmp=libomp -fopenmp-version=51 +// RUN: %check_clang_tidy -std=c11 %s openmp-use-default-none %t -- -- -x c -fopenmp=libomp -fopenmp-version=51 //----------------------------------------------------------------------------// // Null cases. @@ -42,6 +42,15 @@ // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here } +// 'parallel' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p0_3() { +#pragma omp parallel default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'parallel' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here +} + // 'task' directive. // 'task' directive can have 'default' clause, but said clause is not @@ -68,6 +77,15 @@ // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here } +// 'task' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p1_3() { +#pragma omp task default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'task' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here +} + // 'teams' directive. (has to be inside of 'target' directive) // 'teams' directive can have 'default' clause, but said clause is not @@ -97,6 +115,16 @@ // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here } +// 'teams' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p2_3() { +#pragma omp target +#pragma omp teams default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'teams' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here +} + // 'taskloop' directive. // 'taskloop' directive can have 'default' clause, but said clause is not @@ -126,6 +154,16 @@ // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here } +// 'taskloop' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p3_3(const int a) { +#pragma omp taskloop default(firstprivate) + for (int b = 0; b < a; b++) + ; + // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'taskloop' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here +} + //----------------------------------------------------------------------------// // Combined directives. // Let's not test every single possible permutation/combination of directives, @@ -158,3 +196,13 @@ // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'parallel for' specifies 'default(shared)' clause, consider using 'default(none)' clause instead // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here } + +// 'parallel' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p4_3(const int a) { +#pragma omp parallel for default(firstprivate) + for (int b = 0; b < a; b++) + ; + // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'parallel for' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here +} diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -676,9 +676,10 @@ #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) #pragma omp parallel -``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and ``default(firstprivate)``. @@ -3686,6 +3687,7 @@ #pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. @@ -3699,11 +3701,26 @@ #pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. +
Matches if the OpenMP ``default`` clause has ``firstprivate`` kind specified. + +Given + + #pragma omp parallel + #pragma omp parallel default(none) + #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) + +``ompDefaultClause(isFirstPrivateKind())`` matches only ``default(firstprivate)``. +
Matches if the OpenMP directive is allowed to contain the specified OpenMP clause kind. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -7084,10 +7084,12 @@ /// \code /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// #pragma omp parallel /// \endcode /// -/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and +/// ``default(firstprivate)`` extern const internal::VariadicDynCastAllOfMatcherompDefaultClause; @@ -7099,6 +7101,7 @@ /// #pragma omp parallel /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// \endcode /// /// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. @@ -7114,6 +7117,7 @@ /// #pragma omp parallel /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// \endcode /// /// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. @@ -7121,6 +7125,24 @@ return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared; } +/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind +/// specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) +/// \endcode +/// +/// ``ompDefaultClause(isFirstPrivateKind())`` matches only +/// ``default(firstprivate)``. +AST_MATCHER(OMPDefaultClause, isFirstPrivateKind) { + return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_firstprivate; +} + /// Matches if the OpenMP directive is allowed to contain the specified OpenMP /// clause kind. /// diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1332,6 +1332,8 @@ InGroup ; def err_omp_variant_ctx_second_match_extension : Error< "only a single match extension allowed per OpenMP context selector">; +def err_omp_invalid_dsa: Error< + "data-sharing attribute '%0' in '%1' clause requires OpenMP version %2 or above">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -377,6 +377,7 @@ REGISTER_MATCHER(isExpr); REGISTER_MATCHER(isExternC); REGISTER_MATCHER(isFinal); + REGISTER_MATCHER(isFirstPrivateKind); REGISTER_MATCHER(isImplicit); REGISTER_MATCHER(isInStdNamespace); REGISTER_MATCHER(isInTemplateInstantiation); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1451,7 +1451,7 @@ /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. /// /// default-clause: -/// 'default' '(' 'none' | 'shared' ') +/// 'default' '(' 'none' | 'shared' | 'firstprivate' ') /// /// proc_bind-clause: /// 'proc_bind' '(' 'master' | 'close' | 'spread' ') @@ -2771,7 +2771,7 @@ /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. /// /// default-clause: -/// 'default' '(' 'none' | 'shared' ')' +/// 'default' '(' 'none' | 'shared' | 'firstprivate' ')' /// /// proc_bind-clause: /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')' @@ -2784,6 +2784,14 @@ llvm::Optional Val = parseOpenMPSimpleClause(*this, Kind); if (!Val || ParseOnly) return nullptr; + if (getLangOpts().OpenMP < 51 && Kind == OMPC_default && + static_cast (Val.getValue().Type) == + OMP_DEFAULT_firstprivate) { + Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa) + << getOpenMPClauseName(OMPC_firstprivate) + << getOpenMPClauseName(OMPC_default) << "5.1"; + return nullptr; + } return Actions.ActOnOpenMPSimpleClause( Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen, Val.getValue().Loc, Val.getValue().RLoc); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -53,9 +53,10 @@ namespace { /// Default data sharing attributes, which can be applied to directive. enum DefaultDataSharingAttributes { - DSA_unspecified = 0, /// Data sharing attribute not specified. - DSA_none = 1 << 0, /// Default data sharing attribute 'none'. - DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. + DSA_unspecified = 0, /// Data sharing attribute not specified. + DSA_none = 1 << 0, /// Default data sharing attribute 'none'. + DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. + DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. }; /// Stack for tracking declarations used in OpenMP directives and @@ -683,6 +684,11 @@ getTopOfStack().DefaultAttr = DSA_shared; getTopOfStack().DefaultAttrLoc = Loc; } + /// Set default data sharing attribute to firstprivate. + void setDefaultDSAFirstPrivate(SourceLocation Loc) { + getTopOfStack().DefaultAttr = DSA_firstprivate; + getTopOfStack().DefaultAttrLoc = Loc; + } /// Set default data mapping attribute to Modifier:Kind void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, @@ -1167,6 +1173,15 @@ return DVar; case DSA_none: return DVar; + case DSA_firstprivate: + if (VD->getStorageDuration() == SD_Static && + VD->getDeclContext()->isFileContext()) { + DVar.CKind = OMPC_unknown; + } else { + DVar.CKind = OMPC_firstprivate; + } + DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; + return DVar; case DSA_unspecified: // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct, implicitly determined, p.2] @@ -2052,7 +2067,13 @@ // If the variable is artificial and must be captured by value - try to // capture by value. !(isa (D) && !D->hasAttr () && - !cast (D)->getInit()->isGLValue()); + !cast (D)->getInit()->isGLValue()) && + // If the variable is implicitly firstprivate and scalar - capture by + // copy + !(DSAStack->getDefaultDSA() == DSA_firstprivate && + !DSAStack->hasExplicitDSA( + D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) && + !DSAStack->isLoopControlVariable(D, Level).first); } // When passing data by copy, we need to make sure it fits the uintptr size @@ -2179,10 +2200,13 @@ DSAStack->isClauseParsingMode()); // Global shared must not be captured. if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && - (DSAStack->getDefaultDSA() != DSA_none || DVarTop.CKind == OMPC_shared)) + ((DSAStack->getDefaultDSA() != DSA_none && + DSAStack->getDefaultDSA() != DSA_firstprivate) || + DVarTop.CKind == OMPC_shared)) return nullptr; if (DVarPrivate.CKind != OMPC_unknown || - (VD && DSAStack->getDefaultDSA() == DSA_none)) + (VD && (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate))) return VD ? VD : cast (DVarPrivate.PrivateCopy->getDecl()); } return nullptr; @@ -3327,10 +3351,19 @@ // in the construct, and does not have a predetermined data-sharing // attribute, must have its data-sharing attribute explicitly determined // by being listed in a data-sharing attribute clause. - if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && + if (DVar.CKind == OMPC_unknown && + (Stack->getDefaultDSA() == DSA_none || + Stack->getDefaultDSA() == DSA_firstprivate) && isImplicitOrExplicitTaskingRegion(DKind) && VarsWithInheritedDSA.count(VD) == 0) { - VarsWithInheritedDSA[VD] = E; + bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; + if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { + DSAStackTy::DSAVarData DVar = + Stack->getImplicitDSA(VD, /*FromParent=*/false); + InheritedDSA = DVar.CKind == OMPC_unknown; + } + if (InheritedDSA) + VarsWithInheritedDSA[VD] = E; return; } @@ -3432,7 +3465,9 @@ // Define implicit data-sharing attributes for task. DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); - if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && + if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || + (Stack->getDefaultDSA() == DSA_firstprivate && + DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && !Stack->isLoopControlVariable(VD).first) { ImplicitFirstprivate.push_back(E); return; @@ -5334,8 +5369,10 @@ ErrorFound = Res.isInvalid() || ErrorFound; - // Check variables in the clauses if default(none) was specified. - if (DSAStack->getDefaultDSA() == DSA_none) { + // Check variables in the clauses if default(none) or + // default(firstprivate) was specified. + if (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate) { DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); for (OMPClause *C : Clauses) { switch (C->getClauseKind()) { @@ -5444,7 +5481,8 @@ if (P.getFirst()->isImplicit() || isa (P.getFirst())) continue; ErrorFound = true; - if (DSAStack->getDefaultDSA() == DSA_none) { + if (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate) { Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) << P.first << P.second->getSourceRange(); Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); @@ -12783,10 +12821,20 @@ << getOpenMPClauseName(OMPC_default); return nullptr; } - if (Kind == OMP_DEFAULT_none) + + switch (Kind) { + case OMP_DEFAULT_none: DSAStack->setDefaultDSANone(KindKwLoc); - else if (Kind == OMP_DEFAULT_shared) + break; + case OMP_DEFAULT_shared: DSAStack->setDefaultDSAShared(KindKwLoc); + break; + case OMP_DEFAULT_firstprivate: + DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); + break; + default: + llvm_unreachable("DSA unexpected in OpenMP default clause"); + } return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); diff --git a/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp @@ -2,8 +2,17 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + template T tmain(T argc) { int i; @@ -14,12 +23,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -34,7 +43,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -62,12 +71,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -82,7 +91,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -98,5 +107,15 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return (tmain (argc) + tmain (argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain ' requested here}} expected-note {{in instantiation of function template specialization 'tmain ' requested here}} } diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp @@ -2,8 +2,17 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -Wuninitialized -DOMP51 -fopenmp-version=51 + +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized -DOMP51 -fopenmp-version=51 + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + template T tmain(T argc) { int i; @@ -14,12 +23,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -34,7 +43,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -62,12 +71,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -82,7 +91,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -90,6 +99,15 @@ #pragma omp distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OpenMP51 +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif #pragma omp parallel default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp target diff --git a/clang/test/OpenMP/driver.c b/clang/test/OpenMP/driver.c --- a/clang/test/OpenMP/driver.c +++ b/clang/test/OpenMP/driver.c @@ -47,6 +47,7 @@ // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=31 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=40 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=45 | FileCheck --check-prefix=CHECK-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=51 | FileCheck --check-prefix=CHECK-VERSION %s // CHECK-VERSION-NOT: #define _OPENMP diff --git a/clang/test/OpenMP/parallel_default_messages.cpp b/clang/test/OpenMP/parallel_default_messages.cpp --- a/clang/test/OpenMP/parallel_default_messages.cpp +++ b/clang/test/OpenMP/parallel_default_messages.cpp @@ -4,18 +4,25 @@ // RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=40 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-version=31 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-version=30 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=51 -fopenmp -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=51 -fopenmp-simd -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { const int c = 0; #pragma omp parallel default // expected-error {{expected '(' after 'default'}} - #pragma omp parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} - #pragma omp parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp parallel default (shared), default(shared) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'default' clause}} - #pragma omp parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} +#pragma omp parallel default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel default(shared), default(shared) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'default' clause}} +#pragma omp parallel default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp parallel default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -27,5 +34,14 @@ #pragma omp parallel default(none) // ge40-note {{explicit data sharing attribute requested here}} (void)c; // ge40-error {{variable 'c' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp parallel default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_for_default_messages.cpp b/clang/test/OpenMP/parallel_for_default_messages.cpp --- a/clang/test/OpenMP/parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp parallel for default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp parallel for simd default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} expected-error {{variable 'i' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + x++; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + y++; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_master_codegen.cpp b/clang/test/OpenMP/parallel_master_codegen.cpp --- a/clang/test/OpenMP/parallel_master_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_codegen.cpp @@ -118,6 +118,162 @@ #endif +#ifdef CK31 +///==========================================================================/// +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK31 +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK31 + +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// CK31-DAG: %struct.ident_t = type { i32, i32, i32, i32, i8* } +// CK31-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" + +void parallel_master_default_firstprivate() { + int a; +#pragma omp parallel master default(firstprivate) + a++; +} + +// CK31-LABEL: define void @{{.+}}parallel_master{{.+}} +// CK31: [[A_VAL:%.+]] = alloca i32{{.+}} +// CK31: [[A_CASTED:%.+]] = alloca i64 +// CK31: [[ZERO_VAL:%.+]] = load i32, i32* [[A_VAL]] +// CK31: [[CONV:%.+]] = bitcast i64* [[A_CASTED]] to i32* +// CK31: store i32 [[ZERO_VAL]], i32* [[CONV]] +// CK31: [[ONE_VAL:%.+]] = load i64, i64* [[A_CASTED]] +// CK31: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @0, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i64 [[ONE_VAL]]) +// CK31: ret void + +// CK31: [[GLOBAL_TID_ADDR:%.+]] = alloca i32* +// CK31: [[BOUND_TID_ADDR:%.+]] = alloca i32* +// CK31: [[A_ADDR:%.+]] = alloca i64{{.+}} +// CK31: store i32* [[GLOBAL_TID:%.+]], i32** [[GLOBAL_TID_ADDR]]{{.+}} +// CK31: store i32* [[BOUND_TID:%.+]], i32** [[BOUND_TID_ADDR]] +// CK31: store i64 [[A_VAL]], i64* [[A_ADDR]] +// CK31: [[CONV]] = bitcast i64* [[A_ADDR]] +// CK31: [[ZERO_VAL]] = load i32*, i32** [[GLOBAL_TID_ADDR]] +// CK31: [[ONE_VAL]] = load i32, i32* [[ZERO_VAL]] +// CK31: [[TWO_VAL:%.+]] = call i32 @__kmpc_master(%struct.ident_t* @0, i32 [[ONE_VAL]]) +// CK31: [[THREE:%.+]] = icmp ne i32 [[TWO_VAL]], 0 +// CK31: br i1 %3, label [[OMP_IF_THEN:%.+]], label [[OMP_IF_END:%.+]] + +// CK31: [[FOUR:%.+]] = load i32, i32* [[CONV:%.+]] +// CK31: [[INC:%.+]] = add nsw i32 [[FOUR]] +// CK31: store i32 [[INC]], i32* [[CONV]] +// CK31: call void @__kmpc_end_master(%struct.ident_t* @0, i32 [[ONE_VAL]]) +// CK31: br label [[OMP_IF_END]] + +// CK31: ret void + +#endif + +#ifdef CK32 +///==========================================================================/// +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK32 +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK32 + +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// CK32-DAG: %struct.ident_t = type { i32, i32, i32, i32, i8* } +// CK32-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" + +struct St { + int a, b; + static int y; + St() : a(0), b(0) {} + ~St() {} +}; +int St::y = 0; + +void parallel_master_default_firstprivate() { + St a = St(); + static int y = 0; +#pragma omp parallel master default(firstprivate) + { + a.a += 1; + a.b += 1; + y++; + a.y++; + } +} + +// CK32-LABEL: define {{.+}} @{{.+}}parallel_master_default_firstprivate{{.+}} +// CK32: [[A_VAL:%.+]] = alloca %struct.St{{.+}} +// CK32: [[Y_CASTED:%.+]] = alloca i64 +// CK32: call void @[[CTOR:.+]](%struct.St* [[A_VAL]]) +// CK32: [[ZERO:%.+]] = load i32, i32* @{{.+}}parallel_master_default_firstprivate{{.+}} +// CK32: [[CONV:%.+]] = bitcast i64* [[Y_CASTED]] to i32* +// CK32: store i32 [[ZERO]], i32* [[CONV]] +// CK32: [[ONE:%.+]] = load i64, i64* [[Y_CASTED]] +// CK32: call void {{.+}}@{{.+}} %struct.St* [[A_VAL]], i64 [[ONE]]) +// CK32: call void [[DTOR:@.+]](%struct.St* [[A_VAL]]) + +// CK32: [[THIS_ADDR:%.+]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS:%.+]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE:%.+]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: call void [[CTOR_2:.+]](%struct.St* [[THIS_ONE]]) +// CK32: ret void + +// CK32: [[GLOBAL_TID_ADDR:%.+]] = alloca i32* +// CK32: [[BOUND_TID_ADDR:%.+]] = alloca i32* +// CK32: [[A_ADDR:%.+]] = alloca %struct.St +// CK32: [[Y_ADDR:%.+]] = alloca i64 +// CK32: store i32* [[GLOBAL_TID:%.+]], i32** [[GLOBAL_TID_ADDR]] +// CK32: store i32* %.bound_tid., i32** [[BOUND_TID_ADDR]] +// CK32: store %struct.St* [[A_VAL]], %struct.St** [[A_ADDR]]{{.+}} +// CK32: store i64 [[Y:%.+]], i64* [[Y_ADDR]] +// CK32: [[ONE:%.+]] = load i32*, i32** [[GLOBAL_TID_ADDR]] +// CK32: [[TWO:%.+]] = load i32, i32* [[ONE]] +// CK32: [[THREE:%.+]] = call i32 @{{.+}} i32 [[TWO]]) +// CK32: [[FOUR:%.+]] = icmp ne i32 [[THREE]], 0 +// CK32: br i1 [[FOUR]], label [[IF_THEN:%.+]], label [[IF_END:%.+]] + +// CK32: [[A_1:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[ZERO]], i32 0, i32 0 +// CK32: [[FIVE:%.+]] = load i32, i32* [[A_1]] +// CK32: [[ADD:%.+]] = add nsw i32 [[FIVE]], 1 +// CK32: store i32 [[ADD]], i32* [[A_1]] +// CK32: [[B:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[ZERO]], i32 0, i32 1 +// CK32: [[SIX:%.+]] = load i32, i32* [[B]] +// CK32: [[ADD_2:%.+]] = add nsw i32 [[SIX]], 1 +// CK32: store i32 [[ADD_2]], i32* [[B]] +// CK32: [[SEVEN:%.+]] = load i32, i32* [[CONV]] +// CK32: [[INC:%.+]] = add nsw i32 [[SEVEN]], 1 +// CK32: store i32 [[INC]], i32* [[CONV]] +// CK32: [[EIGHT:%.+]] = load i32, i32* [[FUNC:@.+]] +// CK32: [[INC_3:%.+]] = add nsw i32 [[EIGHT]], 1 +// CK32: store i32 [[INC_3]], i32* @{{.+}} +// CK32: call void @{{.+}} i32 [[TWO]]) +// CK32: br label [[IF_END]] + +// CK32: [[DTOR]](%struct.St* [[THIS]]) +// CK32: [[THIS_ADDR]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: call void @_ZN2StD2Ev(%struct.St* [[THIS_ONE]]) + +// CK32: [[THIS_ADDR]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: [[A_VAL]] = getelementptr inbounds %struct.St, %struct.St* [[THIS_ONE]], i32 0, i32 0 +// CK32: store i32 0, i32* [[A_VAL]] +// CK32: [[B_VAL:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[THIS_ONE]], i32 0, i32 1 +// CK32: store i32 0, i32* [[B_VAL]] +// CK32: ret void + +// CK32: [[THIS_ADDR:%.+]] = alloca %struct.St* +// CK32: store %struct.St* %this, %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] + +#endif + #ifdef CK4 ///==========================================================================/// // RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK4 diff --git a/clang/test/OpenMP/parallel_master_default_messages.cpp b/clang/test/OpenMP/parallel_master_default_messages.cpp --- a/clang/test/OpenMP/parallel_master_default_messages.cpp +++ b/clang/test/OpenMP/parallel_master_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp parallel master default // expected-error {{expected '(' after 'default'}} { -#pragma omp parallel master default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel master default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} { -#pragma omp parallel master default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel master default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { #pragma omp parallel master default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} { #pragma omp parallel master default(shared), default(shared) // expected-error {{directive '#pragma omp parallel master' cannot contain more than one 'default' clause}} { -#pragma omp parallel master default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel master default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { foo(); } @@ -37,5 +46,14 @@ ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} } } + +#ifdef OMP51 +#pragma omp parallel master default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_sections_default_messages.cpp b/clang/test/OpenMP/parallel_sections_default_messages.cpp --- a/clang/test/OpenMP/parallel_sections_default_messages.cpp +++ b/clang/test/OpenMP/parallel_sections_default_messages.cpp @@ -7,15 +7,15 @@ int main(int argc, char **argv) { #pragma omp parallel sections default // expected-error {{expected '(' after 'default'}} { -#pragma omp parallel sections default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel sections default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} { -#pragma omp parallel sections default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel sections default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { #pragma omp parallel sections default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} { #pragma omp parallel sections default(shared), default(shared) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'default' clause}} { -#pragma omp parallel sections default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel sections default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { foo(); } diff --git a/clang/test/OpenMP/target_parallel_default_messages.cpp b/clang/test/OpenMP/target_parallel_default_messages.cpp --- a/clang/test/OpenMP/target_parallel_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target parallel default // expected-error {{expected '(' after 'default'}} foo(); - #pragma omp target parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); - #pragma omp target parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target parallel default (shared), default(shared) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'default' clause}} foo(); - #pragma omp target parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -28,5 +37,14 @@ #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifndef OMP51 +#pragma omp target parallel default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_parallel_for_default_messages.cpp b/clang/test/OpenMP/target_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/target_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp target parallel for default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp target parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifndef OMP51 +#pragma omp target parallel for default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (i = 0; i < argc; ++i) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp target parallel for simd default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp target parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'i' must have explicitly specified data sharing attributes}} expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifndef OMP51 +#pragma omp target parallel for simd default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < argc; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_default_messages.cpp b/clang/test/OpenMP/target_teams_default_messages.cpp --- a/clang/test/OpenMP/target_teams_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams default // expected-error {{expected '(' after 'default'}} foo(); -#pragma omp target teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); -#pragma omp target teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target teams default (shared), default(shared) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'default' clause}} foo(); -#pragma omp target teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -24,5 +33,14 @@ #pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifndef OMP51 +#pragma omp target teams default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_default_messages.cpp --- a/clang/test/OpenMP/target_teams_distribute_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_default_messages.cpp @@ -2,24 +2,41 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < 200; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp @@ -2,24 +2,41 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute parallel for default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute parallel for default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute parallel for default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < 200; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp @@ -2,16 +2,25 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute parallel for simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -20,11 +29,19 @@ #pragma omp target teams distribute parallel for simd default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute parallel for simd default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < argc; ++i) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/task_default_messages.cpp b/clang/test/OpenMP/task_default_messages.cpp --- a/clang/test/OpenMP/task_default_messages.cpp +++ b/clang/test/OpenMP/task_default_messages.cpp @@ -2,15 +2,24 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp task default // expected-error {{expected '(' after 'default'}} -#pragma omp task default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} -#pragma omp task default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp task default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp task default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} #pragma omp task default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task default(shared), default(shared) // expected-error {{directive '#pragma omp task' cannot contain more than one 'default' clause}} -#pragma omp task default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp task default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -19,5 +28,13 @@ #pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp task default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp task default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif return 0; } diff --git a/clang/test/OpenMP/task_messages.cpp b/clang/test/OpenMP/task_messages.cpp --- a/clang/test/OpenMP/task_messages.cpp +++ b/clang/test/OpenMP/task_messages.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-version=45 -fopenmp-simd -ferror-limit 200 -std=c++11 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=50 -fopenmp-simd -ferror-limit 200 -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized + void xxx(int argc) { int x; // expected-note {{initialize the variable 'x' to silence this warning}} #pragma omp task @@ -16,6 +19,10 @@ } typedef unsigned long omp_event_handle_t; +namespace { +static int y = 0; +} +static int x = 0; #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}} @@ -52,6 +59,15 @@ #pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp task default(shared) ++a; // expected-error 2 {{variable 'a' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp task default(firstprivate) // expected-note 4 {{explicit data sharing attribute requested here}} +#pragma omp task + { + ++x; // expected-error 2 {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error 2 {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + #pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp task // expected-error@+1 {{calling a private constructor of class 'S'}} diff --git a/clang/test/OpenMP/teams_default_messages.cpp b/clang/test/OpenMP/teams_default_messages.cpp --- a/clang/test/OpenMP/teams_default_messages.cpp +++ b/clang/test/OpenMP/teams_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams default // expected-error {{expected '(' after 'default'}} foo(); #pragma omp target - #pragma omp teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target - #pragma omp teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target #pragma omp teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,7 +30,7 @@ #pragma omp teams default (shared), default(shared) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'default' clause}} foo(); #pragma omp target - #pragma omp teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target @@ -32,5 +41,14 @@ #pragma omp teams default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp target +#pragma omp teams default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif return 0; } diff --git a/clang/test/OpenMP/teams_distribute_default_messages.cpp b/clang/test/OpenMP/teams_distribute_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,21 @@ #pragma omp teams distribute default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp target +#pragma omp teams distribute default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute parallel for default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,21 @@ #pragma omp teams distribute parallel for default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp target +#pragma omp teams distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized -fopenmp-version=51 -DOMP51 + +// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized -fopenmp-version=51 -DOMP51 + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute parallel for simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,20 @@ #pragma omp teams distribute parallel for simd default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OpenMP51 +#pragma omp teams distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp @@ -1,18 +1,23 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized -fopenmp-version=51 -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized -fopenmp-version=51 void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +26,22 @@ #pragma omp teams distribute simd default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#pragma omp target +#pragma omp teams distribute simd default(firstprivate) // expected-note {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + +#pragma omp target +#pragma omp teams distribute simd default(firstprivate) // expected-note {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + return 0; } diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2830,11 +2830,18 @@ EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); const std::string Source4 = R"( +void x() { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher)); } TEST(OMPDefaultClause, isNoneKind) { @@ -2870,10 +2877,17 @@ const std::string Source4 = R"( void x(int x) { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( +void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); } TEST(OMPDefaultClause, isSharedKind) { @@ -2909,10 +2923,63 @@ const std::string Source4 = R"( void x(int x) { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( +void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); +} + +TEST(OMPDefaultClause, isFirstPrivateKind) { + auto Matcher = ompExecutableDirective( + hasAnyClause(ompDefaultClause(isFirstPrivateKind()))); + + const std::string Source0 = R"( +void x() { +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"( +void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher)); + + const std::string Source2 = R"( +void x() { +#pragma omp parallel default(shared) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher)); + + const std::string Source3 = R"( +void x() { +#pragma omp parallel default(none) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher)); + + const std::string Source4 = R"( +void x(int x) { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( +void x(int x) { +#pragma omp parallel num_threads(x) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); } TEST(OMPExecutableDirective, isAllowedToContainClauseKind) { @@ -2947,24 +3014,31 @@ EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); const std::string Source4 = R"( +void x() { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher)); - const std::string Source5 = R"( + const std::string Source6 = R"( void x() { #pragma omp taskyield })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher)); - const std::string Source6 = R"( + const std::string Source7 = R"( void x() { #pragma omp task ; })"; - EXPECT_TRUE(matchesWithOpenMP(Source6, Matcher)); + EXPECT_TRUE(matchesWithOpenMP(Source7, Matcher)); } } // namespace ast_matchers diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -1860,11 +1860,18 @@ EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); const std::string Source4 = R"( +void x() { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); } TEST(MatchFinderAPI, matchesDynamic) { diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.h b/clang/unittests/ASTMatchers/ASTMatchersTest.h --- a/clang/unittests/ASTMatchers/ASTMatchersTest.h +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.h @@ -314,6 +314,20 @@ return matchesConditionally(Code, AMatcher, false, "-fopenmp=libomp"); } +template +testing::AssertionResult matchesWithOpenMP51(const std::string &Code, + const T &AMatcher) { + return matchesConditionally(Code, AMatcher, true, + {"-fopenmp=libomp", "-fopenmp-version=51"}); +} + +template +testing::AssertionResult notMatchesWithOpenMP51(const std::string &Code, + const T &AMatcher) { + return matchesConditionally(Code, AMatcher, false, + {"-fopenmp=libomp", "-fopenmp-version=51"}); +} + template testing::AssertionResult matchAndVerifyResultConditionally(const std::string &Code, const T &AMatcher, diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -537,6 +537,7 @@ __OMP_DEFAULT_KIND(none) __OMP_DEFAULT_KIND(shared) +__OMP_DEFAULT_KIND(firstprivate) __OMP_DEFAULT_KIND(unknown) #undef __OMP_DEFAULT_KIND