From: Arpith Chacko Jacob Date: Thu, 21 Jan 2016 19:57:55 +0000 (+0000) Subject: [OpenMP] Check for at least one map clause on target data directive. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4263daa56970941268278e301f4794b6c90dce7;p=clang [OpenMP] Check for at least one map clause on target data directive. Summary: Adds the following restriction in the OpenMP specifications. OpenMP [2.10.1, Restrictions, p. 97] At least one map clause must appear on the directive. Reviewers: ABataev Differential Revision: http://reviews.llvm.org/D16341 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@258425 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 3273bd18e1..40c8c18a50 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -5618,6 +5618,14 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef Clauses, assert(isa(AStmt) && "Captured statement expected"); + // OpenMP [2.10.1, Restrictions, p. 97] + // At least one map clause must appear on the directive. + if (!HasMapClause(Clauses)) { + Diag(StartLoc, diag::err_omp_no_map_for_directive) << + getOpenMPDirectiveName(OMPD_target_data); + return StmtError(); + } + getCurFunction()->setHasBranchProtectedScope(); return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, diff --git a/test/OpenMP/target_data_ast_print.cpp b/test/OpenMP/target_data_ast_print.cpp index cdff857e56..ed7a965411 100644 --- a/test/OpenMP/target_data_ast_print.cpp +++ b/test/OpenMP/target_data_ast_print.cpp @@ -12,13 +12,13 @@ template T tmain(T argc, T *argv) { T i, j, b, c, d, e, x[20]; -#pragma omp target data +#pragma omp target data map(to: c) i = argc; -#pragma omp target data if (target data: j > 0) +#pragma omp target data map(to: c) if (target data: j > 0) foo(); -#pragma omp target data if (b) +#pragma omp target data map(to: c) if (b) foo(); #pragma omp target data map(c) @@ -48,11 +48,11 @@ T tmain(T argc, T *argv) { // CHECK: template int tmain(int argc, int *argv) { // CHECK-NEXT: int i, j, b, c, d, e, x[20]; -// CHECK-NEXT: #pragma omp target data +// CHECK-NEXT: #pragma omp target data map(to: c) // CHECK-NEXT: i = argc; -// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0) // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: #pragma omp target data map(to: c) if(b) // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: c) // CHECK-NEXT: foo(); @@ -70,11 +70,11 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo(); // CHECK: template char tmain(char argc, char *argv) { // CHECK-NEXT: char i, j, b, c, d, e, x[20]; -// CHECK-NEXT: #pragma omp target data +// CHECK-NEXT: #pragma omp target data map(to: c) // CHECK-NEXT: i = argc; -// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0) // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: #pragma omp target data map(to: c) if(b) // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: c) // CHECK-NEXT: foo(); @@ -92,11 +92,11 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo(); // CHECK: template T tmain(T argc, T *argv) { // CHECK-NEXT: T i, j, b, c, d, e, x[20]; -// CHECK-NEXT: #pragma omp target data +// CHECK-NEXT: #pragma omp target data map(to: c) // CHECK-NEXT: i = argc; -// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0) // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: #pragma omp target data map(to: c) if(b) // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: c) // CHECK-NEXT: foo(); @@ -118,17 +118,17 @@ int main (int argc, char **argv) { static int a; // CHECK: static int a; -#pragma omp target data -// CHECK: #pragma omp target data +#pragma omp target data map(to: c) +// CHECK: #pragma omp target data map(to: c) a=2; // CHECK-NEXT: a = 2; -#pragma omp target data if (target data: b) -// CHECK: #pragma omp target data if(target data: b) +#pragma omp target data map(to: c) if (target data: b) +// CHECK: #pragma omp target data map(to: c) if(target data: b) foo(); // CHECK-NEXT: foo(); -#pragma omp target data if (b > g) -// CHECK: #pragma omp target data if(b > g) +#pragma omp target data map(to: c) if (b > g) +// CHECK: #pragma omp target data map(to: c) if(b > g) foo(); // CHECK-NEXT: foo(); diff --git a/test/OpenMP/target_data_device_messages.cpp b/test/OpenMP/target_data_device_messages.cpp index 9e8e31a28f..a46afee035 100644 --- a/test/OpenMP/target_data_device_messages.cpp +++ b/test/OpenMP/target_data_device_messages.cpp @@ -10,18 +10,19 @@ bool foobool(int argc) { struct S1; // expected-note {{declared here}} int main(int argc, char **argv) { - #pragma omp target data device // expected-error {{expected '(' after 'device'}} - #pragma omp target data device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data device () // expected-error {{expected expression}} - #pragma omp target data device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} -#pragma omp target data device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} - #pragma omp target data device (argc + argc) - #pragma omp target data device (argc), device (argc+1) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'device' clause}} - #pragma omp target data device (S1) // expected-error {{'S1' does not refer to a value}} - #pragma omp target data device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} - #pragma omp target device (-10u) - #pragma omp target device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + int a; + #pragma omp target data map(to: a) device // expected-error {{expected '(' after 'device'}} + #pragma omp target data map(to: a) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) device () // expected-error {{expected expression}} + #pragma omp target data map(to: a) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} +#pragma omp target data map(to: a) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target data map(to: a) device (argc + argc) + #pragma omp target data map(to: a) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'device' clause}} + #pragma omp target data map(to: a) device (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target data map(to: a) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + #pragma omp target map(to: a) device (-10u) + #pragma omp target map(to: a) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} foo(); return 0; diff --git a/test/OpenMP/target_data_if_messages.cpp b/test/OpenMP/target_data_if_messages.cpp index 77edefa48b..ec6fe26921 100644 --- a/test/OpenMP/target_data_if_messages.cpp +++ b/test/OpenMP/target_data_if_messages.cpp @@ -10,22 +10,23 @@ bool foobool(int argc) { struct S1; // expected-note {{declared here}} int main(int argc, char **argv) { - #pragma omp target data if // expected-error {{expected '(' after 'if'}} - #pragma omp target data if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if () // expected-error {{expected expression}} - #pragma omp target data if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} - #pragma omp target data if (argc > 0 ? argv[1] : argv[2]) - #pragma omp target data if (argc + argc) - #pragma omp target data if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}} - #pragma omp target data if (S1) // expected-error {{'S1' does not refer to a value}} - #pragma omp target data if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if(target data : argc) - #pragma omp target data if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}} - #pragma omp target data if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}} - #pragma omp target data if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + int a; + #pragma omp target data map(to: a) if // expected-error {{expected '(' after 'if'}} + #pragma omp target data map(to: a) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if () // expected-error {{expected expression}} + #pragma omp target data map(to: a) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} + #pragma omp target data map(to: a) if (argc > 0 ? argv[1] : argv[2]) + #pragma omp target data map(to: a) if (argc + argc) + #pragma omp target data map(to: a) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}} + #pragma omp target data map(to: a) if (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target data map(to: a) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if(target data : argc) + #pragma omp target data map(to: a) if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}} + #pragma omp target data map(to: a) if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}} + #pragma omp target data map(to: a) if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); return 0; diff --git a/test/OpenMP/target_data_messages.c b/test/OpenMP/target_data_messages.c index cd60d85a90..153b437729 100644 --- a/test/OpenMP/target_data_messages.c +++ b/test/OpenMP/target_data_messages.c @@ -3,19 +3,22 @@ void foo() { } int main(int argc, char **argv) { + int a; + #pragma omp target data // expected-error {{expected at least one map clause for '#pragma omp target data'}} + {} L1: foo(); - #pragma omp target data + #pragma omp target data map(a) { foo(); goto L1; // expected-error {{use of undeclared label 'L1'}} } goto L2; // expected-error {{use of undeclared label 'L2'}} - #pragma omp target data + #pragma omp target data map(a) L2: foo(); - #pragma omp target data(i) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} + #pragma omp target data map(a)(i) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} { foo(); }