]> granicus.if.org Git - clang/commitdiff
[OpenMP] Generate better diagnostics for cancel and cancellation point
authorJonas Hahnfeld <Hahnfeld@itc.rwth-aachen.de>
Wed, 22 Feb 2017 06:49:10 +0000 (06:49 +0000)
committerJonas Hahnfeld <Hahnfeld@itc.rwth-aachen.de>
Wed, 22 Feb 2017 06:49:10 +0000 (06:49 +0000)
checkNestingOfRegions uses CancelRegion to determine whether cancel and
cancellation point are valid in the given nesting. This leads to unuseful
diagnostics if CancelRegion is invalid. The given test case has produced:
  region cannot be closely nested inside 'parallel' region

As a solution, introduce checkCancelRegion and call it first to get the
expected error:
  one of 'for', 'parallel', 'sections' or 'taskgroup' is expected

Differential Revision: https://reviews.llvm.org/D30135

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295808 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOpenMP.cpp
test/OpenMP/cancel_messages.cpp
test/OpenMP/cancellation_point_messages.cpp

index 87115054b0ca3510760523bd2e3306f4d111c5ca..7d4799745505638b0a84dcd86e6cce751fa0680d 100644 (file)
@@ -1956,7 +1956,23 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
   return SR;
 }
 
-static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
+static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
+                              OpenMPDirectiveKind CancelRegion,
+                              SourceLocation StartLoc) {
+  // CancelRegion is only needed for cancel and cancellation_point.
+  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
+    return false;
+
+  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
+      CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
+    return false;
+
+  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
+      << getOpenMPDirectiveName(CancelRegion);
+  return true;
+}
+
+static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
                                   OpenMPDirectiveKind CurrentRegion,
                                   const DeclarationNameInfo &CurrentName,
                                   OpenMPDirectiveKind CancelRegion,
@@ -2256,7 +2272,9 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
   StmtResult Res = StmtError();
-  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
+  // First check CancelRegion which is then used in checkNestingOfRegions.
+  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
+      checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
                             StartLoc))
     return StmtError();
 
@@ -5860,12 +5878,6 @@ StmtResult
 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
                                             SourceLocation EndLoc,
                                             OpenMPDirectiveKind CancelRegion) {
-  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
-      CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
-    Diag(StartLoc, diag::err_omp_wrong_cancel_region)
-        << getOpenMPDirectiveName(CancelRegion);
-    return StmtError();
-  }
   if (DSAStack->isParentNowaitRegion()) {
     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
     return StmtError();
@@ -5882,12 +5894,6 @@ StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
                                             SourceLocation StartLoc,
                                             SourceLocation EndLoc,
                                             OpenMPDirectiveKind CancelRegion) {
-  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
-      CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
-    Diag(StartLoc, diag::err_omp_wrong_cancel_region)
-        << getOpenMPDirectiveName(CancelRegion);
-    return StmtError();
-  }
   if (DSAStack->isParentNowaitRegion()) {
     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
     return StmtError();
index e23b5c337bc805b84499442698efd92c0a24467c..f8bbe2c36bea378020a2d9188d536c2d9e8434dd 100644 (file)
@@ -4,8 +4,16 @@ int main(int argc, char **argv) {
 #pragma omp cancellation       // expected-error {{expected an OpenMP directive}}
 #pragma omp cancel // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   ;
+#pragma omp parallel
+  {
+#pragma omp cancel // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancel parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancel'}}
 #pragma omp cancel unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+#pragma omp parallel
+  {
+#pragma omp cancel unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancel sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
 #pragma omp cancel for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
 #pragma omp cancel taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
index 2324915e83f8221b2f3fa131c525d981fa11f683..21b0e9c2fa2dbc9f0b353137ec53fdd9cb338287 100644 (file)
@@ -4,8 +4,16 @@ int main(int argc, char **argv) {
 #pragma omp cancellation       // expected-error {{expected an OpenMP directive}}
 #pragma omp cancellation point // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   ;
+#pragma omp parallel
+  {
+#pragma omp cancellation point // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancellation point parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancellation point'}}
 #pragma omp cancellation point unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+#pragma omp parallel
+  {
+#pragma omp cancellation point unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancellation point sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
 #pragma omp cancellation point for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
 #pragma omp cancellation point taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}