[clang] bfc2dbe - [OpenACC] Implement data construct 'at least 1 of ... clauses' rule

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 16 11:53:02 PST 2024


Author: erichkeane
Date: 2024-12-16T11:52:57-08:00
New Revision: bfc2dbe02e00f0023c0a2d58b53cdbd1f4139f02

URL: https://github.com/llvm/llvm-project/commit/bfc2dbe02e00f0023c0a2d58b53cdbd1f4139f02
DIFF: https://github.com/llvm/llvm-project/commit/bfc2dbe02e00f0023c0a2d58b53cdbd1f4139f02.diff

LOG: [OpenACC] Implement data construct 'at least 1 of ... clauses' rule

All 4 of the 'data' constructs have a requirement that at least 1 of a
small list of clauses must appear on the construct.  This patch
implements that restriction, and updates all of the tests it takes to
do so.

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Sema/SemaOpenACC.h
    clang/lib/Parse/ParseOpenACC.cpp
    clang/lib/Sema/SemaOpenACC.cpp
    clang/lib/Sema/TreeTransform.h
    clang/test/AST/ast-print-openacc-data-construct.cpp
    clang/test/ParserOpenACC/parse-clauses.c
    clang/test/ParserOpenACC/parse-constructs.c
    clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp
    clang/test/SemaOpenACC/combined-construct-if-clause.c
    clang/test/SemaOpenACC/compute-construct-device_type-clause.c
    clang/test/SemaOpenACC/compute-construct-if-clause.c
    clang/test/SemaOpenACC/data-construct-async-ast.cpp
    clang/test/SemaOpenACC/data-construct-copy-clause.c
    clang/test/SemaOpenACC/data-construct-copyin-clause.c
    clang/test/SemaOpenACC/data-construct-copyout-clause.c
    clang/test/SemaOpenACC/data-construct-create-clause.c
    clang/test/SemaOpenACC/data-construct-default-clause.c
    clang/test/SemaOpenACC/data-construct-delete-clause.c
    clang/test/SemaOpenACC/data-construct-device_type-ast.cpp
    clang/test/SemaOpenACC/data-construct-device_type-clause.c
    clang/test/SemaOpenACC/data-construct-no_create-clause.c
    clang/test/SemaOpenACC/data-construct-use_device-clause.c
    clang/test/SemaOpenACC/data-construct.cpp
    clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 77f84a89db2fc9..3a3ef917c6a8f4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12804,6 +12804,8 @@ def err_acc_loop_terminating_condition
 def err_acc_loop_not_monotonic
     : Error<"OpenACC '%0' variable must monotonically increase or decrease "
             "('++', '--', or compound assignment)">;
+def err_acc_construct_one_clause_of
+    : Error<"OpenACC '%0' construct must have at least one %1 clause">;
 
 // AMDGCN builtins diagnostics
 def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;

diff  --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index 78056d03680017..4b92af507af4ea 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -662,7 +662,8 @@ class SemaOpenACC : public SemaBase {
   /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
   /// happen before any associated declarations or statements have been parsed.
   /// This function is only called when we are parsing a 'statement' context.
-  bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc);
+  bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
+                               ArrayRef<const OpenACCClause *> Clauses);
 
   /// Called after the directive, including its clauses, have been parsed and
   /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES

diff  --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 570dba811aca86..af175a465eb79a 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -1512,8 +1512,8 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() {
   ParsingOpenACCDirectiveRAII DirScope(*this);
 
   OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
-  if (getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
-                                                     DirInfo.StartLoc))
+  if (getActions().OpenACC().ActOnStartStmtDirective(
+          DirInfo.DirKind, DirInfo.StartLoc, DirInfo.Clauses))
     return StmtError();
 
   StmtResult AssocStmt;

diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 79822bf583195e..11c18358a3aa01 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -3526,8 +3526,35 @@ void SemaOpenACC::ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body) {
   }
 }
 
-bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
-                                          SourceLocation StartLoc) {
+namespace {
+// Get a list of clause Kinds for diagnosing a list, joined by a commas and an
+// 'or'.
+std::string GetListOfClauses(llvm::ArrayRef<OpenACCClauseKind> Clauses) {
+  assert(!Clauses.empty() && "empty clause list not supported");
+
+  std::string Output;
+  llvm::raw_string_ostream OS{Output};
+
+  if (Clauses.size() == 1) {
+    OS << '\'' << Clauses[0] << '\'';
+    return Output;
+  }
+
+  llvm::ArrayRef<OpenACCClauseKind> AllButLast{Clauses.begin(),
+                                               Clauses.end() - 1};
+
+  llvm::interleave(
+      AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; },
+      [&] { OS << ", "; });
+
+  OS << " or \'" << Clauses.back() << '\'';
+  return Output;
+}
+} // namespace
+
+bool SemaOpenACC::ActOnStartStmtDirective(
+    OpenACCDirectiveKind K, SourceLocation StartLoc,
+    ArrayRef<const OpenACCClause *> Clauses) {
   SemaRef.DiscardCleanupsInEvaluationContext();
   SemaRef.PopExpressionEvaluationContext();
 
@@ -3554,6 +3581,59 @@ bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
         << OpenACCClauseKind::Tile;
   }
 
+  // OpenACC3.3 2.6.5: At least one copy, copyin, copyout, create, no_create,
+  // present, deviceptr, attach, or default clause must appear on a 'data'
+  // construct.
+  if (K == OpenACCDirectiveKind::Data &&
+      llvm::find_if(Clauses,
+                    llvm::IsaPred<OpenACCCopyClause, OpenACCCopyInClause,
+                                  OpenACCCopyOutClause, OpenACCCreateClause,
+                                  OpenACCNoCreateClause, OpenACCPresentClause,
+                                  OpenACCDevicePtrClause, OpenACCAttachClause,
+                                  OpenACCDefaultClause>) == Clauses.end())
+    return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
+           << K
+           << GetListOfClauses(
+                  {OpenACCClauseKind::Copy, OpenACCClauseKind::CopyIn,
+                   OpenACCClauseKind::CopyOut, OpenACCClauseKind::Create,
+                   OpenACCClauseKind::NoCreate, OpenACCClauseKind::Present,
+                   OpenACCClauseKind::DevicePtr, OpenACCClauseKind::Attach,
+                   OpenACCClauseKind::Default});
+
+  // OpenACC3.3 2.6.6: At least one copyin, create, or attach clause must appear
+  // on an enter data directive.
+  if (K == OpenACCDirectiveKind::EnterData &&
+      llvm::find_if(Clauses,
+                    llvm::IsaPred<OpenACCCopyInClause, OpenACCCreateClause,
+                                  OpenACCAttachClause>) == Clauses.end())
+    return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
+           << K
+           << GetListOfClauses({
+                  OpenACCClauseKind::CopyIn,
+                  OpenACCClauseKind::Create,
+                  OpenACCClauseKind::Attach,
+              });
+  // OpenACC3.3 2.6.6: At least one copyout, delete, or detach clause must
+  // appear on an exit data directive.
+  if (K == OpenACCDirectiveKind::ExitData &&
+      llvm::find_if(Clauses,
+                    llvm::IsaPred<OpenACCCopyOutClause, OpenACCDeleteClause,
+                                  OpenACCDetachClause>) == Clauses.end())
+    return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
+           << K
+           << GetListOfClauses({
+                  OpenACCClauseKind::CopyOut,
+                  OpenACCClauseKind::Delete,
+                  OpenACCClauseKind::Detach,
+              });
+
+  // OpenACC3.3 2.8: At least 'one use_device' clause must appear.
+  if (K == OpenACCDirectiveKind::HostData &&
+      llvm::find_if(Clauses, llvm::IsaPred<OpenACCUseDeviceClause>) ==
+          Clauses.end())
+    return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
+           << K << GetListOfClauses({OpenACCClauseKind::UseDevice});
+
   return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
 }
 

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c9bb079a9bcb34..04167e71d33f8a 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12178,8 +12178,8 @@ StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
       getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
                                               C->clauses());
 
-  if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
-                                                  C->getBeginLoc()))
+  if (getSema().OpenACC().ActOnStartStmtDirective(
+          C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
     return StmtError();
 
   // Transform Structured Block.
@@ -12205,8 +12205,8 @@ TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
       getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
                                               C->clauses());
 
-  if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
-                                                  C->getBeginLoc()))
+  if (getSema().OpenACC().ActOnStartStmtDirective(
+          C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
     return StmtError();
 
   // Transform Loop.
@@ -12231,8 +12231,8 @@ StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
       getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
                                               C->clauses());
 
-  if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
-                                                  C->getBeginLoc()))
+  if (getSema().OpenACC().ActOnStartStmtDirective(
+          C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
     return StmtError();
 
   // Transform Loop.
@@ -12256,8 +12256,8 @@ TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
   llvm::SmallVector<OpenACCClause *> TransformedClauses =
       getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
                                               C->clauses());
-  if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
-                                                  C->getBeginLoc()))
+  if (getSema().OpenACC().ActOnStartStmtDirective(
+          C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
     return StmtError();
 
   SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
@@ -12280,8 +12280,8 @@ StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
   llvm::SmallVector<OpenACCClause *> TransformedClauses =
       getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
                                               C->clauses());
-  if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
-                                                  C->getBeginLoc()))
+  if (getSema().OpenACC().ActOnStartStmtDirective(
+          C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
     return StmtError();
 
   return getDerived().RebuildOpenACCEnterDataConstruct(
@@ -12297,8 +12297,8 @@ StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
   llvm::SmallVector<OpenACCClause *> TransformedClauses =
       getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
                                               C->clauses());
-  if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
-                                                  C->getBeginLoc()))
+  if (getSema().OpenACC().ActOnStartStmtDirective(
+          C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
     return StmtError();
 
   return getDerived().RebuildOpenACCExitDataConstruct(
@@ -12314,8 +12314,8 @@ StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
   llvm::SmallVector<OpenACCClause *> TransformedClauses =
       getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
                                               C->clauses());
-  if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
-                                                  C->getBeginLoc()))
+  if (getSema().OpenACC().ActOnStartStmtDirective(
+          C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
     return StmtError();
 
   SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(

diff  --git a/clang/test/AST/ast-print-openacc-data-construct.cpp b/clang/test/AST/ast-print-openacc-data-construct.cpp
index 7ad0a43e322a21..f568ae5ce63467 100644
--- a/clang/test/AST/ast-print-openacc-data-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-data-construct.cpp
@@ -10,8 +10,8 @@ void foo() {
 #pragma acc data default(none)
   ;
 
-// CHECK: #pragma acc data device_type(int)
-#pragma acc data device_type(int)
+// CHECK: #pragma acc data default(none) device_type(int)
+#pragma acc data default(none) device_type(int)
   ;
 
 // CHECK: #pragma acc enter data copyin(Var)

diff  --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index 487dc79f538085..2e884c472c2ec1 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -4,20 +4,27 @@
 
 void func() {
 
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data finalize
 
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data finalize finalize
 
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{invalid OpenACC clause 'invalid'}}
 #pragma acc exit data finalize invalid
 
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{invalid OpenACC clause 'invalid'}}
 #pragma acc exit data finalize invalid invalid finalize
 
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data wait finalize
 
+  // expected-error at +1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
 #pragma acc host_data if_present
 
+  // expected-error at +1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
 #pragma acc host_data if_present, if_present
 
   // expected-error at +4{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}}

diff  --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c
index d3b1ccb48c0349..4a6c31cc9b0a9d 100644
--- a/clang/test/ParserOpenACC/parse-constructs.c
+++ b/clang/test/ParserOpenACC/parse-constructs.c
@@ -54,12 +54,15 @@ void func() {
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
 #pragma acc kernels clause list
   for(;;){}
+    // expected-error at +2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
 #pragma acc data clause list
   for(;;){}
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
 #pragma acc enter data clause list
   for(;;){}
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
 #pragma acc exit data clause list
   for(;;){}
@@ -75,6 +78,7 @@ void func() {
   // expected-error at +1{{expected identifier}}
 #pragma acc exit }
   for(;;){}
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
 #pragma acc host_data clause list
   for(;;){}

diff  --git a/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp b/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp
index 31078ea7a0de9e..f2be6622007c3f 100644
--- a/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp
@@ -214,6 +214,7 @@ void no_other_directives() {
 #pragma acc serial loop collapse(2)
   for(unsigned i = 0; i < 5; ++i) {
     for(unsigned j = 0; j < 5; ++j) {
+    // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data
       ;
     }
@@ -221,6 +222,7 @@ void no_other_directives() {
   // expected-note at +1{{active 'collapse' clause defined here}}
 #pragma acc kernels loop collapse(2)
   for(unsigned i = 0; i < 5; ++i) {
+    // expected-error at +2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
     // expected-error at +1{{OpenACC 'data' construct cannot appear in intervening code of a 'kernels loop' with a 'collapse' clause}}
 #pragma acc data
     for(unsigned j = 0; j < 5; ++j) {

diff  --git a/clang/test/SemaOpenACC/combined-construct-if-clause.c b/clang/test/SemaOpenACC/combined-construct-if-clause.c
index 09bd4dd190b6b2..5580fdfe22b7b8 100644
--- a/clang/test/SemaOpenACC/combined-construct-if-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-if-clause.c
@@ -43,6 +43,7 @@ void BoolExpr(int *I, float *F) {
 #pragma acc kernels loop if (*I < *F)
   for (unsigned i = 0; i < 5; ++i);
 
+  // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data if (*I < *F)
   for (unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop if (*I < *F)

diff  --git a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
index cccb50ee55582d..c1a77abf5c3f12 100644
--- a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
@@ -34,8 +34,10 @@ void uses() {
 #pragma acc kernels dtype(MACRO)
   while(1);
 
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'device_type' clause is not valid on 'enter data' directive}}
 #pragma acc enter data device_type(I)
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'dtype' clause is not valid on 'enter data' directive}}
 #pragma acc enter data dtype(I)
 

diff  --git a/clang/test/SemaOpenACC/compute-construct-if-clause.c b/clang/test/SemaOpenACC/compute-construct-if-clause.c
index 20d42a17cba141..c0ea88f06284d8 100644
--- a/clang/test/SemaOpenACC/compute-construct-if-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-if-clause.c
@@ -43,6 +43,7 @@ void BoolExpr(int *I, float *F) {
 #pragma acc kernels if (*I < *F)
   while(0);
 
+  // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data if (*I < *F)
   while(0);
 #pragma acc parallel loop if (*I < *F)

diff  --git a/clang/test/SemaOpenACC/data-construct-async-ast.cpp b/clang/test/SemaOpenACC/data-construct-async-ast.cpp
index d16cc6f4807976..fb6a37108ae4e5 100644
--- a/clang/test/SemaOpenACC/data-construct-async-ast.cpp
+++ b/clang/test/SemaOpenACC/data-construct-async-ast.cpp
@@ -15,21 +15,30 @@ void TemplUses() {
   // CHECK-NEXT: FunctionDecl{{.*}}TemplUses
   // CHECK-NEXT: CompoundStmt
 
-#pragma acc data async(some_int())
+  // CHECK-NEXT: DeclStmt
+  // CHECK-NEXT: VarDecl
+  T t;
+
+#pragma acc data default(none) async(some_int())
   ;
   // CHECK-NEXT: OpenACCDataConstruct{{.*}}data
+  // CHECK-NEXT: default(none)
   // CHECK-NEXT: async clause
   // CHECK-NEXT: CallExpr{{.*}}'int'
   // CHECK-NEXT: ImplicitCastExpr
   // CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
   // CHECK-NEXT: NullStmt
-#pragma acc enter data async(T{})
+#pragma acc enter data copyin(t) async(T{})
   // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data
+  // CHECK-NEXT: copyin clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'T'
   // CHECK-NEXT: async clause
   // CHECK-NEXT: CXXUnresolvedConstructExpr{{.*}} 'T' 'T' list
   // CHECK-NEXT: InitListExpr{{.*}}'void'
-#pragma acc exit data async
+#pragma acc exit data copyout(t) async
   // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data
+  // CHECK-NEXT: copyout clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'T'
   // CHECK-NEXT: async clause
 
   // Instantiations
@@ -38,7 +47,11 @@ void TemplUses() {
   // CHECK-NEXT: BuiltinType{{.*}} 'int'
   // CHECK-NEXT: CompoundStmt
 
+  // CHECK-NEXT: DeclStmt
+  // CHECK-NEXT: VarDecl
+
   // CHECK-NEXT: OpenACCDataConstruct{{.*}}data
+  // CHECK-NEXT: default(none)
   // CHECK-NEXT: async clause
   // CHECK-NEXT: CallExpr{{.*}}'int'
   // CHECK-NEXT: ImplicitCastExpr
@@ -46,11 +59,15 @@ void TemplUses() {
   // CHECK-NEXT: NullStmt
 
   // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data
+  // CHECK-NEXT: copyin clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'int'
   // CHECK-NEXT: async clause
   // CHECK-NEXT: CXXFunctionalCastExpr
   // CHECK-NEXT: InitListExpr{{.*}}'int'
 
   // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data
+  // CHECK-NEXT: copyout clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'int'
   // CHECK-NEXT: async clause
 }
 void Inst() {

diff  --git a/clang/test/SemaOpenACC/data-construct-copy-clause.c b/clang/test/SemaOpenACC/data-construct-copy-clause.c
index 035463c22c688d..882a0bc87e0035 100644
--- a/clang/test/SemaOpenACC/data-construct-copy-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-copy-clause.c
@@ -56,10 +56,13 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
 #pragma acc data copy((float)ArrayParam[2])
   ;
 
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'copy' clause is not valid on 'enter data' directive}}
 #pragma acc enter data copy(LocalInt)
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{OpenACC 'pcopy' clause is not valid on 'exit data' directive}}
 #pragma acc exit data pcopy(LocalInt)
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'host_data' directive}}
 #pragma acc host_data present_or_copy(LocalInt)
   ;

diff  --git a/clang/test/SemaOpenACC/data-construct-copyin-clause.c b/clang/test/SemaOpenACC/data-construct-copyin-clause.c
index 36d190b81480fa..370cc7000f8d89 100644
--- a/clang/test/SemaOpenACC/data-construct-copyin-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-copyin-clause.c
@@ -63,8 +63,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
 #pragma acc data copyin(invalid:(float)ArrayParam[2])
   ;
 
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{OpenACC 'copyin' clause is not valid on 'exit data' directive}}
 #pragma acc exit data copyin(LocalInt)
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'host_data' directive}}
 #pragma acc host_data pcopyin(LocalInt)
   ;

diff  --git a/clang/test/SemaOpenACC/data-construct-copyout-clause.c b/clang/test/SemaOpenACC/data-construct-copyout-clause.c
index 77c19d80ca7b36..0f9d5f2ad5c83b 100644
--- a/clang/test/SemaOpenACC/data-construct-copyout-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-copyout-clause.c
@@ -63,8 +63,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
 #pragma acc data copyout(invalid:(float)ArrayParam[2])
   ;
 
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'enter data' directive}}
 #pragma acc enter data copyout(LocalInt)
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'host_data' directive}}
 #pragma acc host_data pcopyout(LocalInt)
   ;

diff  --git a/clang/test/SemaOpenACC/data-construct-create-clause.c b/clang/test/SemaOpenACC/data-construct-create-clause.c
index 08210f85d5924e..4972bdca4b85dc 100644
--- a/clang/test/SemaOpenACC/data-construct-create-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-create-clause.c
@@ -63,8 +63,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
 #pragma acc data create(invalid:(float)ArrayParam[2])
   ;
 
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{OpenACC 'create' clause is not valid on 'exit data' directive}}
 #pragma acc exit data create(LocalInt)
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{OpenACC 'pcreate' clause is not valid on 'host_data' directive}}
 #pragma acc host_data pcreate(LocalInt)
   ;

diff  --git a/clang/test/SemaOpenACC/data-construct-default-clause.c b/clang/test/SemaOpenACC/data-construct-default-clause.c
index e09004d7404c0c..150d3ec22dcdac 100644
--- a/clang/test/SemaOpenACC/data-construct-default-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-default-clause.c
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 %s -fopenacc -verify
 
 void use() {
+  // expected-error at +2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
   // expected-error at +1{{invalid value for 'default' clause; expected 'present' or 'none'}}
 #pragma acc data default(garbage)
   ;
@@ -12,12 +13,15 @@ void use() {
   // expected-note at +1{{previous clause is here}}
 #pragma acc data default(none) default(present)
   ;
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'default' clause is not valid on 'enter data' directive}}
 #pragma acc enter data default(present)
   ;
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{OpenACC 'default' clause is not valid on 'exit data' directive}}
 #pragma acc exit data default(none)
   ;
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{OpenACC 'default' clause is not valid on 'host_data' directive}}
 #pragma acc host_data default(present)
   ;

diff  --git a/clang/test/SemaOpenACC/data-construct-delete-clause.c b/clang/test/SemaOpenACC/data-construct-delete-clause.c
index d936882ae94214..05093dbc4e01bc 100644
--- a/clang/test/SemaOpenACC/data-construct-delete-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-delete-clause.c
@@ -37,11 +37,14 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
   // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
 #pragma acc exit data delete((float)ArrayParam[2])
 
+  // expected-error at +2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
   // expected-error at +1{{OpenACC 'delete' clause is not valid on 'data' directive}}
 #pragma acc data delete(LocalInt)
   ;
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'delete' clause is not valid on 'enter data' directive}}
 #pragma acc enter data delete(LocalInt)
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{OpenACC 'delete' clause is not valid on 'host_data' directive}}
 #pragma acc host_data delete(LocalInt)
   ;

diff  --git a/clang/test/SemaOpenACC/data-construct-device_type-ast.cpp b/clang/test/SemaOpenACC/data-construct-device_type-ast.cpp
index 23f00490f0674f..1f497bb7afcc4e 100644
--- a/clang/test/SemaOpenACC/data-construct-device_type-ast.cpp
+++ b/clang/test/SemaOpenACC/data-construct-device_type-ast.cpp
@@ -13,9 +13,10 @@ void TemplUses() {
   // CHECK-NEXT: FunctionDecl{{.*}}TemplUses
   // CHECK-NEXT: CompoundStmt
 
-#pragma acc data device_type(T) dtype(T)
+#pragma acc data default(none) device_type(T) dtype(T)
   ;
   // CHECK-NEXT: OpenACCDataConstruct{{.*}} data
+  // CHECK-NEXT: default(none)
   // CHECK-NEXT: device_type(T)
   // CHECK-NEXT: dtype(T)
   // CHECK-NEXT: NullStmt
@@ -28,6 +29,7 @@ void TemplUses() {
 
   // Argument to 'device-type' is just an identifier, so we don't transform it.
   // CHECK-NEXT: OpenACCDataConstruct{{.*}} data
+  // CHECK-NEXT: default(none)
   // CHECK-NEXT: device_type(T)
   // CHECK-NEXT: dtype(T)
   // CHECK-NEXT: NullStmt

diff  --git a/clang/test/SemaOpenACC/data-construct-device_type-clause.c b/clang/test/SemaOpenACC/data-construct-device_type-clause.c
index f675c2fa6a8800..a467287b93e0cc 100644
--- a/clang/test/SemaOpenACC/data-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-device_type-clause.c
@@ -2,51 +2,52 @@
 
 void uses() {
   int Var;
-#pragma acc data device_type(foo) async
+#pragma acc data default(none) device_type(foo) async
   ;
-#pragma acc data device_type(foo) wait
+#pragma acc data default(none) device_type(foo) wait
   ;
-#pragma acc data device_type(foo) dtype(false)
+#pragma acc data default(none) device_type(foo) dtype(false)
   ;
-#pragma acc data dtype(foo) device_type(false)
+#pragma acc data default(none) dtype(foo) device_type(false)
   ;
 
   // expected-error at +2{{OpenACC clause 'if' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) if(1)
+#pragma acc data default(none) device_type(foo) if(1)
   ;
   // expected-error at +2{{OpenACC clause 'copy' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) copy(Var)
+#pragma acc data default(none) device_type(foo) copy(Var)
   ;
   // expected-error at +2{{OpenACC clause 'copyin' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) copyin(Var)
+#pragma acc data default(none) device_type(foo) copyin(Var)
   ;
   // expected-error at +2{{OpenACC clause 'copyout' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) copyout(Var)
+#pragma acc data default(none) device_type(foo) copyout(Var)
   ;
   // expected-error at +2{{OpenACC clause 'create' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) create(Var)
+#pragma acc data default(none) device_type(foo) create(Var)
   ;
   // expected-error at +2{{OpenACC clause 'no_create' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) no_create(Var)
+#pragma acc data default(none) device_type(foo) no_create(Var)
   ;
   // expected-error at +2{{OpenACC clause 'present' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) present(Var)
+#pragma acc data default(none) device_type(foo) present(Var)
   ;
   // expected-error at +2{{OpenACC clause 'deviceptr' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) deviceptr(Var)
+#pragma acc data default(none) device_type(foo) deviceptr(Var)
   ;
   // expected-error at +2{{OpenACC clause 'attach' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(foo) attach(Var)
+#pragma acc data default(none) device_type(foo) attach(Var)
   ;
+  // expected-error at +3{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
   // expected-error at +2{{OpenACC clause 'default' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
 #pragma acc data device_type(foo) default(none)

diff  --git a/clang/test/SemaOpenACC/data-construct-no_create-clause.c b/clang/test/SemaOpenACC/data-construct-no_create-clause.c
index 74bc972ced64db..0eb459eb0009a3 100644
--- a/clang/test/SemaOpenACC/data-construct-no_create-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-no_create-clause.c
@@ -48,10 +48,13 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
 #pragma acc data no_create((float)ArrayParam[2])
   ;
 
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{OpenACC 'no_create' clause is not valid on 'exit data' directive}}
 #pragma acc exit data no_create(LocalInt)
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'no_create' clause is not valid on 'enter data' directive}}
 #pragma acc enter data no_create(LocalInt)
+  // expected-error at +2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +1{{OpenACC 'no_create' clause is not valid on 'host_data' directive}}
 #pragma acc host_data no_create(LocalInt)
   ;

diff  --git a/clang/test/SemaOpenACC/data-construct-use_device-clause.c b/clang/test/SemaOpenACC/data-construct-use_device-clause.c
index d0f74585759cff..c2e7fd17f8c8d6 100644
--- a/clang/test/SemaOpenACC/data-construct-use_device-clause.c
+++ b/clang/test/SemaOpenACC/data-construct-use_device-clause.c
@@ -52,11 +52,14 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
 #pragma acc host_data use_device((float)ArrayParam[2])
   ;
 
+  // expected-error at +2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
   // expected-error at +1{{OpenACC 'use_device' clause is not valid on 'data' directive}}
 #pragma acc data use_device(LocalInt)
   ;
+  // expected-error at +2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
   // expected-error at +1{{OpenACC 'use_device' clause is not valid on 'enter data' directive}}
 #pragma acc enter data use_device(LocalInt)
+  // expected-error at +2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
   // expected-error at +1{{OpenACC 'use_device' clause is not valid on 'exit data' directive}}
 #pragma acc exit data use_device(LocalInt)
 }

diff  --git a/clang/test/SemaOpenACC/data-construct.cpp b/clang/test/SemaOpenACC/data-construct.cpp
index 309d0300d5a9e1..4c868b68e332e4 100644
--- a/clang/test/SemaOpenACC/data-construct.cpp
+++ b/clang/test/SemaOpenACC/data-construct.cpp
@@ -3,18 +3,20 @@
 void HasStmt() {
   {
     // expected-error at +2{{expected statement}}
-#pragma acc data
+#pragma acc data default(none)
   }
+
+  int I;
   {
     // expected-error at +2{{expected statement}}
-#pragma acc host_data
+#pragma acc host_data use_device(I)
   }
   // Don't have statements, so this is fine.
   {
-#pragma acc enter data
+#pragma acc enter data copyin(I)
   }
   {
-#pragma acc exit data
+#pragma acc exit data copyout(I)
   }
 }
 
@@ -41,20 +43,22 @@ void AtLeastOneOf() {
 #pragma acc data default(none)
   ;
 
-  // OpenACC TODO: The following 'data' directives should diagnose, since they
-  // don't have at least one of the above clauses.
-
+    // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data if(Var)
   ;
 
+    // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data async
   ;
 
+    // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data wait
   ;
 
+    // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data device_type(*)
   ;
+    // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data
   ;
 
@@ -63,12 +67,13 @@ void AtLeastOneOf() {
 #pragma acc enter data create(Var)
 #pragma acc enter data attach(VarPtr)
 
-  // OpenACC TODO: The following 'enter data' directives should diagnose, since
-  // they don't have at least one of the above clauses.
-
+  // expected-error at +1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
 #pragma acc enter data if(Var)
+  // expected-error at +1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
 #pragma acc enter data async
+  // expected-error at +1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
 #pragma acc enter data wait
+  // expected-error at +1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}}
 #pragma acc enter data
 
   // Exit Data
@@ -76,25 +81,28 @@ void AtLeastOneOf() {
 #pragma acc exit data delete(Var)
 #pragma acc exit data detach(VarPtr)
 
-  // OpenACC TODO: The following 'exit data' directives should diagnose, since
-  // they don't have at least one of the above clauses.
-
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data if(Var)
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data async
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data wait
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data finalize
+  // expected-error at +1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}}
 #pragma acc exit data
 
   // Host Data
 #pragma acc host_data use_device(Var)
   ;
-  // OpenACC TODO: The following 'host_data' directives should diagnose, since
-  // they don't have at least one of the above clauses.
 
+  // expected-error at +1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
 #pragma acc host_data if(Var)
   ;
+  // expected-error at +1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
 #pragma acc host_data if_present
   ;
+  // expected-error at +1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
 #pragma acc host_data
   ;
 }
@@ -103,47 +111,47 @@ void DataRules() {
   int Var;
   // expected-error at +2{{OpenACC clause 'copy' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) copy(Var)
+#pragma acc data default(none) device_type(*) copy(Var)
   ;
   // expected-error at +2{{OpenACC clause 'copyin' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) copyin(Var)
+#pragma acc data default(none) device_type(*) copyin(Var)
   ;
   // expected-error at +2{{OpenACC clause 'copyout' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) copyout(Var)
+#pragma acc data default(none) device_type(*) copyout(Var)
   ;
   // expected-error at +2{{OpenACC clause 'create' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) create(Var)
+#pragma acc data default(none) device_type(*) create(Var)
   ;
   // expected-error at +2{{OpenACC clause 'no_create' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) no_create(Var)
+#pragma acc data default(none) device_type(*) no_create(Var)
   ;
   // expected-error at +2{{OpenACC clause 'present' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) present(Var)
+#pragma acc data default(none) device_type(*) present(Var)
   ;
   // expected-error at +2{{OpenACC clause 'deviceptr' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) deviceptr(Var)
+#pragma acc data default(none) device_type(*) deviceptr(Var)
   ;
   // expected-error at +2{{OpenACC clause 'attach' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) attach(Var)
+#pragma acc data default(none) device_type(*) attach(Var)
   ;
   // expected-error at +2{{OpenACC clause 'default' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) default(none)
+#pragma acc data default(none) device_type(*) default(none)
   ;
   // expected-error at +2{{OpenACC clause 'if' may not follow a 'device_type' clause in a 'data' construct}}
   // expected-note at +1{{previous clause is here}}
-#pragma acc data device_type(*) if(Var)
+#pragma acc data default(none) device_type(*) if(Var)
   ;
-#pragma acc data device_type(*) async
+#pragma acc data default(none) device_type(*) async
   ;
-#pragma acc data device_type(*) wait
+#pragma acc data default(none) device_type(*) wait
   ;
 }
 
@@ -165,6 +173,7 @@ struct HasMembers {
 
 void HostDataRules() {
   int Var, Var2;
+  // expected-error at +3{{OpenACC 'host_data' construct must have at least one 'use_device' clause}}
   // expected-error at +2{{OpenACC 'if' clause cannot appear more than once on a 'host_data' directive}}
   // expected-note at +1{{previous clause is here}}
 #pragma acc host_data if(Var) if (Var2)

diff  --git a/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp b/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp
index b401dd891629aa..4d45d1107d03b0 100644
--- a/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp
+++ b/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp
@@ -323,6 +323,7 @@ void no_other_directives() {
 #pragma acc loop collapse(2)
   for(unsigned i = 0; i < 5; ++i) {
     for(unsigned j = 0; j < 5; ++j) {
+    // expected-error at +1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
 #pragma acc data
       ;
     }
@@ -330,6 +331,7 @@ void no_other_directives() {
   // expected-note at +1{{active 'collapse' clause defined here}}
 #pragma acc loop collapse(2)
   for(unsigned i = 0; i < 5; ++i) {
+    // expected-error at +2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
     // expected-error at +1{{OpenACC 'data' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
 #pragma acc data
     for(unsigned j = 0; j < 5; ++j) {


        


More information about the cfe-commits mailing list