Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -5546,6 +5546,14 @@ 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, Index: test/OpenMP/target_data_ast_print.cpp =================================================================== --- test/OpenMP/target_data_ast_print.cpp +++ test/OpenMP/target_data_ast_print.cpp @@ -12,13 +12,13 @@ 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 @@ // 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 @@ // 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 @@ // 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 @@ 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(); Index: test/OpenMP/target_data_device_messages.cpp =================================================================== --- test/OpenMP/target_data_device_messages.cpp +++ test/OpenMP/target_data_device_messages.cpp @@ -10,18 +10,19 @@ 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; Index: test/OpenMP/target_data_if_messages.cpp =================================================================== --- test/OpenMP/target_data_if_messages.cpp +++ test/OpenMP/target_data_if_messages.cpp @@ -10,22 +10,23 @@ 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; Index: test/OpenMP/target_data_messages.c =================================================================== --- test/OpenMP/target_data_messages.c +++ 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(); }