summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp17
-rw-r--r--clang/test/OpenMP/single_ast_print.cpp20
-rw-r--r--clang/test/OpenMP/single_copyprivate_messages.cpp2
4 files changed, 39 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9c097028b93..5b5528e4f76 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7430,6 +7430,10 @@ def note_omp_nested_teams_construct_here : Note<
"nested teams construct here">;
def note_omp_nested_statement_here : Note<
"%select{statement|directive}0 outside teams construct here">;
+def err_omp_single_copyprivate_with_nowait : Error<
+ "the 'copyprivate' clause must not be used with the 'nowait' clause">;
+def note_omp_nowait_clause_here : Note<
+ "'nowait' clause is here">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 0d349068860..cd03f996102 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3048,6 +3048,23 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope();
+ // OpenMP [2.7.3, single Construct, Restrictions]
+ // The copyprivate clause must not be used with the nowait clause.
+ OMPClause *Nowait = nullptr;
+ OMPClause *Copyprivate = nullptr;
+ for (auto *Clause : Clauses) {
+ if (Clause->getClauseKind() == OMPC_nowait)
+ Nowait = Clause;
+ else if (Clause->getClauseKind() == OMPC_copyprivate)
+ Copyprivate = Clause;
+ if (Copyprivate && Nowait) {
+ Diag(Copyprivate->getLocStart(),
+ diag::err_omp_single_copyprivate_with_nowait);
+ Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
+ return StmtError();
+ }
+ }
+
return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
}
diff --git a/clang/test/OpenMP/single_ast_print.cpp b/clang/test/OpenMP/single_ast_print.cpp
index 65a007e271c..b9eba9d7eb2 100644
--- a/clang/test/OpenMP/single_ast_print.cpp
+++ b/clang/test/OpenMP/single_ast_print.cpp
@@ -14,10 +14,16 @@ T tmain(T argc) {
static T a;
// CHECK: static T a;
#pragma omp parallel private(g)
-#pragma omp single private(argc, b), firstprivate(c, d), nowait copyprivate(g)
+#pragma omp single private(argc, b), firstprivate(c, d), nowait
foo();
// CHECK-NEXT: #pragma omp parallel private(g)
- // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait copyprivate(g)
+ // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait
+ // CHECK-NEXT: foo();
+#pragma omp parallel private(g)
+#pragma omp single private(argc, b), firstprivate(c, d), copyprivate(g)
+ foo();
+ // CHECK-NEXT: #pragma omp parallel private(g)
+ // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) copyprivate(g)
// CHECK-NEXT: foo();
return T();
}
@@ -27,10 +33,16 @@ int main(int argc, char **argv) {
static int a;
// CHECK: static int a;
#pragma omp parallel private(g)
-#pragma omp single private(argc, b), firstprivate(argv, c), nowait copyprivate(g)
+#pragma omp single private(argc, b), firstprivate(argv, c), nowait
+ foo();
+ // CHECK-NEXT: #pragma omp parallel private(g)
+ // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait
+ // CHECK-NEXT: foo();
+#pragma omp parallel private(g)
+#pragma omp single private(argc, b), firstprivate(c, d), copyprivate(g)
foo();
// CHECK-NEXT: #pragma omp parallel private(g)
- // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait copyprivate(g)
+ // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) copyprivate(g)
// CHECK-NEXT: foo();
return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
}
diff --git a/clang/test/OpenMP/single_copyprivate_messages.cpp b/clang/test/OpenMP/single_copyprivate_messages.cpp
index 7bb145c6d32..252f2e6a4ff 100644
--- a/clang/test/OpenMP/single_copyprivate_messages.cpp
+++ b/clang/test/OpenMP/single_copyprivate_messages.cpp
@@ -152,6 +152,8 @@ int main(int argc, char **argv) {
#pragma omp parallel
#pragma omp single firstprivate(i) copyprivate(i) // expected-error {{firstprivate variable cannot be copyprivate}} expected-note {{defined as firstprivate}}
foo();
+#pragma omp single copyprivate(i) nowait // expected-error {{the 'copyprivate' clause must not be used with the 'nowait' clause}} expected-note {{'nowait' clause is here}}
+ foo();
return tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char>' requested here}}
}
OpenPOWER on IntegriCloud