[clang] 9b95929 - [OPENMP50]Do not allow several scan directives in the same parent

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 20 12:50:32 PDT 2020


Author: Alexey Bataev
Date: 2020-03-20T15:45:31-04:00
New Revision: 9b95929a26e133bc3cae9f29f91e8e351d233840

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

LOG: [OPENMP50]Do not allow several scan directives in the same parent
region.

According to OpenMP 5.0, exactly one scan directive must appear in the loop body of an enclosing worksharing-loop, worksharing-loop SIMD, or simd construct on which a reduction clause with the inscan modifier is present.

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaOpenMP.cpp
    clang/test/OpenMP/scan_messages.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 39d29060372f..90845ecf5468 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9833,6 +9833,10 @@ def err_omp_prohibited_region_critical_same_name : Error<
   "cannot nest 'critical' regions having the same name %0">;
 def note_omp_previous_critical_region : Note<
   "previous 'critical' region starts here">;
+def err_omp_several_scan_directives_in_region : Error<
+  "exactly one 'scan' directive must appear in the loop body of an enclosing directive">;
+def note_omp_previous_scan_directive : Note<
+  "previous 'scan' directive used here">;
 def err_omp_sections_not_compound_stmt : Error<
   "the statement for '#pragma omp sections' must be a compound statement">;
 def err_omp_parallel_sections_not_compound_stmt : Error<

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 861b75a774d8..309ab4afa69d 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -154,6 +154,7 @@ class DSAStackTy {
     bool CancelRegion = false;
     bool LoopStart = false;
     bool BodyComplete = false;
+    SourceLocation PrevScanLocation;
     SourceLocation InnerTeamsRegionLoc;
     /// Reference to the taskgroup task_reduction reference expression.
     Expr *TaskgroupReductionRef = nullptr;
@@ -781,6 +782,22 @@ class DSAStackTy {
     return Top ? Top->CancelRegion : false;
   }
 
+  /// Mark that parent region already has scan directive.
+  void setParentHasScanDirective(SourceLocation Loc) {
+    if (SharingMapTy *Parent = getSecondOnStackOrNull())
+      Parent->PrevScanLocation = Loc;
+  }
+  /// Return true if current region has inner cancel construct.
+  bool doesParentHasScanDirective() const {
+    const SharingMapTy *Top = getSecondOnStackOrNull();
+    return Top ? Top->PrevScanLocation.isValid() : false;
+  }
+  /// Return true if current region has inner cancel construct.
+  SourceLocation getParentScanDirectiveLoc() const {
+    const SharingMapTy *Top = getSecondOnStackOrNull();
+    return Top ? Top->PrevScanLocation : SourceLocation();
+  }
+
   /// Set collapse value for the region.
   void setAssociatedLoops(unsigned Val) {
     getTopOfStack().AssociatedLoops = Val;
@@ -8795,11 +8812,21 @@ StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
                                           SourceLocation StartLoc,
                                           SourceLocation EndLoc) {
+  // Check that exactly one clause is specified.
   if (Clauses.size() != 1) {
     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
          diag::err_omp_scan_single_clause_expected);
     return StmtError();
   }
+  // Check that only one instance of scan directives is used in the same outer
+  // region.
+  if (DSAStack->doesParentHasScanDirective()) {
+    Diag(StartLoc, diag::err_omp_several_scan_directives_in_region);
+    Diag(DSAStack->getParentScanDirectiveLoc(),
+         diag::note_omp_previous_scan_directive);
+    return StmtError();
+  }
+  DSAStack->setParentHasScanDirective(StartLoc);
   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
 }
 

diff  --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp
index ea4e273e9d0b..3be998d0f96e 100644
--- a/clang/test/OpenMP/scan_messages.cpp
+++ b/clang/test/OpenMP/scan_messages.cpp
@@ -54,12 +54,12 @@ T tmain(T argc) {
 #pragma omp simd
   for (int i = 0; i < 10; ++i)
   switch (argc) {
-#pragma omp scan inclusive(argc)
+#pragma omp scan inclusive(argc) // expected-note 2 {{previous 'scan' directive used here}}
   case 1:
-#pragma omp scan inclusive(argc)
+#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
     break;
   default: {
-#pragma omp scan inclusive(argc)
+#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
   } break;
   }
 #pragma omp simd
@@ -133,12 +133,12 @@ int main(int argc, char **argv) {
 #pragma omp simd
   for (int i = 0; i < 10; ++i)
   switch (argc) {
-#pragma omp scan inclusive(argc)
+#pragma omp scan inclusive(argc) // expected-note 2 {{previous 'scan' directive used here}}
   case 1:
-#pragma omp scan inclusive(argc)
+#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
     break;
   default: {
-#pragma omp scan inclusive(argc)
+#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
   } break;
   }
 #pragma omp simd


        


More information about the cfe-commits mailing list