[clang] [OpenACC] Implement 'return' branch-out of Compute Construct (PR #82814)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 23 11:05:35 PST 2024


https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/82814

>From cdbf2a137ed7ba0a6d40f955072ef636ee93b292 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Fri, 23 Feb 2024 10:36:31 -0800
Subject: [PATCH 1/2] [OpenACC] Implement 'return' branch-out of Compute
 Construct

Like with 'break'/'continue', returning out of a compute construct is
ill-formed, so this implements the diagnostic.  However, unlike the
OpenMP implementation of this same diagnostic, OpenACC doesn't have a
concept of 'capture region', so this is implemented as just checking the
'scope'.
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  5 +++--
 clang/include/clang/Sema/Scope.h              | 13 ++++++++++++
 clang/lib/Sema/SemaStmt.cpp                   | 16 +++++++++++----
 clang/test/SemaOpenACC/no-branch-in-out.c     | 20 +++++++++++++++++++
 clang/test/SemaOpenACC/no-branch-in-out.cpp   | 17 ++++++++++++++++
 5 files changed, 65 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/SemaOpenACC/no-branch-in-out.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..608265ca78432f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12203,6 +12203,7 @@ def warn_acc_clause_unimplemented
 def err_acc_construct_appertainment
     : Error<"OpenACC construct '%0' cannot be used here; it can only "
             "be used in a statement context">;
-def err_acc_branch_in_out
-    : Error<"invalid branch %select{out of|into}0 OpenACC Compute Construct">;
+def err_acc_branch_in_out_compute_construct
+    : Error<"invalid %select{branch|return}0 %select{out of|into}1 OpenACC "
+            "Compute Construct">;
 } // end of sema component.
diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index e7f166fe3461fd..370133cd7429b0 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -521,6 +521,19 @@ class Scope {
     return getFlags() & Scope::OpenACCComputeConstructScope;
   }
 
+  bool isInOpenACCComputeConstructScope() const {
+    for (const Scope *S = this; S; S = S->getParent()) {
+      if (S->getFlags() & Scope::OpenACCComputeConstructScope)
+        return true;
+      else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
+                                Scope::BlockScope | Scope::TemplateParamScope |
+                                Scope::FunctionPrototypeScope |
+                                Scope::AtCatchScope | Scope::ObjCMethodScope))
+        return false;
+    }
+    return false;
+  }
+
   /// Determine whether this scope is a while/do/for statement, which can have
   /// continue statements embedded into it.
   bool isContinueScope() const {
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index fcad09a63662ba..0a5c2b23a90c8e 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3361,8 +3361,9 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
   // of a compute construct counts as 'branching out of' the compute construct,
   // so diagnose here.
   if (S->isOpenACCComputeConstructScope())
-    return StmtError(Diag(ContinueLoc, diag::err_acc_branch_in_out)
-                     << /*out of */ 0);
+    return StmtError(
+        Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)
+        << /*branch*/ 0 << /*out of */ 0);
 
   CheckJumpOutOfSEHFinally(*this, ContinueLoc, *S);
 
@@ -3390,8 +3391,9 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
   if (S->isOpenACCComputeConstructScope() ||
       (S->isLoopScope() && S->getParent() &&
        S->getParent()->isOpenACCComputeConstructScope()))
-    return StmtError(Diag(BreakLoc, diag::err_acc_branch_in_out)
-                     << /*out of */ 0);
+    return StmtError(
+        Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)
+        << /*branch*/ 0 << /*out of */ 0);
 
   CheckJumpOutOfSEHFinally(*this, BreakLoc, *S);
 
@@ -3947,6 +3949,12 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
       RetValExp, nullptr, /*RecoverUncorrectedTypos=*/true);
   if (RetVal.isInvalid())
     return StmtError();
+
+  if (getCurScope()->isInOpenACCComputeConstructScope())
+    return StmtError(
+        Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)
+        << /*return*/ 1 << /*out of */ 0);
+
   StmtResult R =
       BuildReturnStmt(ReturnLoc, RetVal.get(), /*AllowRecovery=*/true);
   if (R.isInvalid() || ExprEvalContexts.back().isDiscardedStatementContext())
diff --git a/clang/test/SemaOpenACC/no-branch-in-out.c b/clang/test/SemaOpenACC/no-branch-in-out.c
index 33a171f1b68d51..f8fb40a1ca8f72 100644
--- a/clang/test/SemaOpenACC/no-branch-in-out.c
+++ b/clang/test/SemaOpenACC/no-branch-in-out.c
@@ -93,3 +93,23 @@ void BreakContinue() {
 
 }
 
+void Return() {
+#pragma acc parallel
+  {
+    return;// expected-error{{invalid return out of OpenACC Compute Construct}}
+  }
+
+#pragma acc parallel
+  {
+    {
+      return;// expected-error{{invalid return out of OpenACC Compute Construct}}
+    }
+  }
+
+#pragma acc parallel
+  {
+    for (int i = 0; i < 5; ++i) {
+      return;// expected-error{{invalid return out of OpenACC Compute Construct}}
+    }
+  }
+}
diff --git a/clang/test/SemaOpenACC/no-branch-in-out.cpp b/clang/test/SemaOpenACC/no-branch-in-out.cpp
new file mode 100644
index 00000000000000..232e372cedd357
--- /dev/null
+++ b/clang/test/SemaOpenACC/no-branch-in-out.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -verify -fopenacc -fcxx-exceptions
+
+
+void ReturnTest() {
+#pragma acc parallel
+  {
+    (void)[]() { return; };
+  }
+
+#pragma acc parallel
+  {
+    try {}
+    catch(...){
+      return; // expected-error{{invalid return out of OpenACC Compute Construct}}
+    }
+  }
+}

>From 8681cfe5676f8abf690b4e7861f74224cd9eacca Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Fri, 23 Feb 2024 11:05:05 -0800
Subject: [PATCH 2/2] Clang-format

---
 clang/include/clang/Sema/Scope.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 370133cd7429b0..b6b5a1f3479a25 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -525,10 +525,10 @@ class Scope {
     for (const Scope *S = this; S; S = S->getParent()) {
       if (S->getFlags() & Scope::OpenACCComputeConstructScope)
         return true;
-      else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
-                                Scope::BlockScope | Scope::TemplateParamScope |
-                                Scope::FunctionPrototypeScope |
-                                Scope::AtCatchScope | Scope::ObjCMethodScope))
+      else if (S->getFlags() &
+               (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
+                Scope::TemplateParamScope | Scope::FunctionPrototypeScope |
+                Scope::AtCatchScope | Scope::ObjCMethodScope))
         return false;
     }
     return false;



More information about the cfe-commits mailing list