Skip to content

Commit

Permalink
[OpenACC] Implement 'return' branch-out of Compute Construct (#82814)
Browse files Browse the repository at this point in the history
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'.
  • Loading branch information
erichkeane committed Feb 26, 2024
1 parent 8ce81e5 commit 668cd1c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 6 deletions.
5 changes: 3 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -12210,6 +12210,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.
13 changes: 13 additions & 0 deletions clang/include/clang/Sema/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
16 changes: 12 additions & 4 deletions clang/lib/Sema/SemaStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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())
Expand Down
20 changes: 20 additions & 0 deletions clang/test/SemaOpenACC/no-branch-in-out.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
}
}
}
17 changes: 17 additions & 0 deletions clang/test/SemaOpenACC/no-branch-in-out.cpp
Original file line number Diff line number Diff line change
@@ -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}}
}
}
}

0 comments on commit 668cd1c

Please sign in to comment.