Skip to content

Commit 668cd1c

Browse files
authored
[OpenACC] Implement 'return' branch-out of Compute Construct (llvm#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'.
1 parent 8ce81e5 commit 668cd1c

File tree

5 files changed

+65
-6
lines changed

5 files changed

+65
-6
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12210,6 +12210,7 @@ def warn_acc_clause_unimplemented
1221012210
def err_acc_construct_appertainment
1221112211
: Error<"OpenACC construct '%0' cannot be used here; it can only "
1221212212
"be used in a statement context">;
12213-
def err_acc_branch_in_out
12214-
: Error<"invalid branch %select{out of|into}0 OpenACC Compute Construct">;
12213+
def err_acc_branch_in_out_compute_construct
12214+
: Error<"invalid %select{branch|return}0 %select{out of|into}1 OpenACC "
12215+
"Compute Construct">;
1221512216
} // end of sema component.

clang/include/clang/Sema/Scope.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,19 @@ class Scope {
521521
return getFlags() & Scope::OpenACCComputeConstructScope;
522522
}
523523

524+
bool isInOpenACCComputeConstructScope() const {
525+
for (const Scope *S = this; S; S = S->getParent()) {
526+
if (S->getFlags() & Scope::OpenACCComputeConstructScope)
527+
return true;
528+
else if (S->getFlags() &
529+
(Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
530+
Scope::TemplateParamScope | Scope::FunctionPrototypeScope |
531+
Scope::AtCatchScope | Scope::ObjCMethodScope))
532+
return false;
533+
}
534+
return false;
535+
}
536+
524537
/// Determine whether this scope is a while/do/for statement, which can have
525538
/// continue statements embedded into it.
526539
bool isContinueScope() const {

clang/lib/Sema/SemaStmt.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3361,8 +3361,9 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
33613361
// of a compute construct counts as 'branching out of' the compute construct,
33623362
// so diagnose here.
33633363
if (S->isOpenACCComputeConstructScope())
3364-
return StmtError(Diag(ContinueLoc, diag::err_acc_branch_in_out)
3365-
<< /*out of */ 0);
3364+
return StmtError(
3365+
Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)
3366+
<< /*branch*/ 0 << /*out of */ 0);
33663367

33673368
CheckJumpOutOfSEHFinally(*this, ContinueLoc, *S);
33683369

@@ -3390,8 +3391,9 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
33903391
if (S->isOpenACCComputeConstructScope() ||
33913392
(S->isLoopScope() && S->getParent() &&
33923393
S->getParent()->isOpenACCComputeConstructScope()))
3393-
return StmtError(Diag(BreakLoc, diag::err_acc_branch_in_out)
3394-
<< /*out of */ 0);
3394+
return StmtError(
3395+
Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)
3396+
<< /*branch*/ 0 << /*out of */ 0);
33953397

33963398
CheckJumpOutOfSEHFinally(*this, BreakLoc, *S);
33973399

@@ -3947,6 +3949,12 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
39473949
RetValExp, nullptr, /*RecoverUncorrectedTypos=*/true);
39483950
if (RetVal.isInvalid())
39493951
return StmtError();
3952+
3953+
if (getCurScope()->isInOpenACCComputeConstructScope())
3954+
return StmtError(
3955+
Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)
3956+
<< /*return*/ 1 << /*out of */ 0);
3957+
39503958
StmtResult R =
39513959
BuildReturnStmt(ReturnLoc, RetVal.get(), /*AllowRecovery=*/true);
39523960
if (R.isInvalid() || ExprEvalContexts.back().isDiscardedStatementContext())

clang/test/SemaOpenACC/no-branch-in-out.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,23 @@ void BreakContinue() {
9393

9494
}
9595

96+
void Return() {
97+
#pragma acc parallel
98+
{
99+
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
100+
}
101+
102+
#pragma acc parallel
103+
{
104+
{
105+
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
106+
}
107+
}
108+
109+
#pragma acc parallel
110+
{
111+
for (int i = 0; i < 5; ++i) {
112+
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
113+
}
114+
}
115+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 %s -verify -fopenacc -fcxx-exceptions
2+
3+
4+
void ReturnTest() {
5+
#pragma acc parallel
6+
{
7+
(void)[]() { return; };
8+
}
9+
10+
#pragma acc parallel
11+
{
12+
try {}
13+
catch(...){
14+
return; // expected-error{{invalid return out of OpenACC Compute Construct}}
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)