https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/82814
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'. >From cdbf2a137ed7ba0a6d40f955072ef636ee93b292 Mon Sep 17 00:00:00 2001 From: erichkeane <eke...@nvidia.com> Date: Fri, 23 Feb 2024 10:36:31 -0800 Subject: [PATCH] [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}} + } + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits