Skip to content

Commit 86f4b4d

Browse files
authored
[OpenACC] Implement Compute Construct 'goto' in/out logic (#83326)
Compute Constructs do not permit jumping in/out of them, so this patch implements this for 'goto' as a followup to the other patches that have done the same thing. It does this by modifying the JumpDiagnostics to work with this, plus setting the function to needing jump diagnostics if we discover a goto or label inside of a Compute Construct.
1 parent e08fe57 commit 86f4b4d

File tree

4 files changed

+234
-2
lines changed

4 files changed

+234
-2
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12214,4 +12214,8 @@ def err_acc_construct_appertainment
1221412214
def err_acc_branch_in_out_compute_construct
1221512215
: Error<"invalid %select{branch|return}0 %select{out of|into}1 OpenACC "
1221612216
"Compute Construct">;
12217+
def note_acc_branch_into_compute_construct
12218+
: Note<"invalid branch into OpenACC Compute Construct">;
12219+
def note_acc_branch_out_of_compute_construct
12220+
: Note<"invalid branch out of OpenACC Compute Construct">;
1221712221
} // end of sema component.

clang/lib/Sema/JumpDiagnostics.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,16 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S,
604604
break;
605605
}
606606

607+
case Stmt::OpenACCComputeConstructClass: {
608+
unsigned NewParentScope = Scopes.size();
609+
OpenACCComputeConstruct *CC = cast<OpenACCComputeConstruct>(S);
610+
Scopes.push_back(GotoScope(
611+
ParentScope, diag::note_acc_branch_into_compute_construct,
612+
diag::note_acc_branch_out_of_compute_construct, CC->getBeginLoc()));
613+
BuildScopeInformation(CC->getStructuredBlock(), NewParentScope);
614+
return;
615+
}
616+
607617
default:
608618
if (auto *ED = dyn_cast<OMPExecutableDirective>(S)) {
609619
if (!ED->isStandaloneDirective()) {
@@ -936,11 +946,16 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
936946
if (Scopes[I].InDiag == diag::note_protected_by_seh_finally) {
937947
S.Diag(From->getBeginLoc(), diag::warn_jump_out_of_seh_finally);
938948
break;
939-
}
940-
if (Scopes[I].InDiag == diag::note_omp_protected_structured_block) {
949+
} else if (Scopes[I].InDiag ==
950+
diag::note_omp_protected_structured_block) {
941951
S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope);
942952
S.Diag(To->getBeginLoc(), diag::note_omp_exits_structured_block);
943953
break;
954+
} else if (Scopes[I].InDiag ==
955+
diag::note_acc_branch_into_compute_construct) {
956+
S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope);
957+
S.Diag(Scopes[I].Loc, diag::note_acc_branch_out_of_compute_construct);
958+
return;
944959
}
945960
}
946961
}

clang/lib/Sema/SemaStmt.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,11 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
567567
Diag(IdentLoc, diag::warn_reserved_extern_symbol)
568568
<< TheDecl << static_cast<int>(Status);
569569

570+
// If this label is in a compute construct scope, we need to make sure we
571+
// check gotos in/out.
572+
if (getCurScope()->isInOpenACCComputeConstructScope())
573+
setFunctionHasBranchProtectedScope();
574+
570575
// Otherwise, things are good. Fill in the declaration and return it.
571576
LabelStmt *LS = new (Context) LabelStmt(IdentLoc, TheDecl, SubStmt);
572577
TheDecl->setStmt(LS);
@@ -3304,6 +3309,12 @@ StmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc,
33043309
SourceLocation LabelLoc,
33053310
LabelDecl *TheDecl) {
33063311
setFunctionHasBranchIntoScope();
3312+
3313+
// If this goto is in a compute construct scope, we need to make sure we check
3314+
// gotos in/out.
3315+
if (getCurScope()->isInOpenACCComputeConstructScope())
3316+
setFunctionHasBranchProtectedScope();
3317+
33073318
TheDecl->markUsed(Context);
33083319
return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
33093320
}
@@ -3332,6 +3343,11 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
33323343

33333344
setFunctionHasIndirectGoto();
33343345

3346+
// If this goto is in a compute construct scope, we need to make sure we
3347+
// check gotos in/out.
3348+
if (getCurScope()->isInOpenACCComputeConstructScope())
3349+
setFunctionHasBranchProtectedScope();
3350+
33353351
return new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E);
33363352
}
33373353

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

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,200 @@ void Return() {
113113
}
114114
}
115115
}
116+
117+
void Goto() {
118+
int j;
119+
#pragma acc parallel // expected-note{{invalid branch out of OpenACC Compute Construct}}
120+
while(j) {
121+
if (j <3)
122+
goto LABEL; // expected-error{{cannot jump from this goto statement to its label}}
123+
}
124+
125+
LABEL:
126+
{}
127+
128+
goto LABEL_IN; // expected-error{{cannot jump from this goto statement to its label}}
129+
130+
#pragma acc parallel // expected-note{{invalid branch into OpenACC Compute Construct}}
131+
for(int i = 0; i < 5; ++i) {
132+
LABEL_IN:
133+
{}
134+
}
135+
136+
#pragma acc parallel
137+
for(int i = 0; i < 5; ++i) {
138+
LABEL_NOT_CALLED:
139+
{}
140+
}
141+
142+
#pragma acc parallel
143+
{
144+
goto ANOTHER_LOOP; // expected-error{{cannot jump from this goto statement to its label}}
145+
146+
}
147+
#pragma acc parallel// expected-note{{invalid branch into OpenACC Compute Construct}}
148+
149+
{
150+
ANOTHER_LOOP:
151+
{}
152+
}
153+
154+
#pragma acc parallel
155+
{
156+
while (j) {
157+
--j;
158+
if (j < 3)
159+
goto LABEL2;
160+
161+
if (j > 4)
162+
break;
163+
}
164+
LABEL2:
165+
{}
166+
}
167+
168+
#pragma acc parallel
169+
do {
170+
if (j < 3)
171+
goto LABEL3;
172+
173+
if (j > 4)
174+
break; // expected-error{{invalid branch out of OpenACC Compute Construct}}
175+
176+
LABEL3:
177+
{}
178+
} while (j);
179+
180+
LABEL4:
181+
{}
182+
#pragma acc parallel// expected-note{{invalid branch out of OpenACC Compute Construct}}
183+
{
184+
goto LABEL4;// expected-error{{cannot jump from this goto statement to its label}}
185+
}
186+
187+
#pragma acc parallel// expected-note{{invalid branch into OpenACC Compute Construct}}
188+
189+
{
190+
LABEL5:
191+
{}
192+
}
193+
194+
{
195+
goto LABEL5;// expected-error{{cannot jump from this goto statement to its label}}
196+
}
197+
198+
#pragma acc parallel
199+
{
200+
LABEL6:
201+
{}
202+
goto LABEL6;
203+
204+
}
205+
206+
#pragma acc parallel
207+
goto LABEL7; // expected-error{{cannot jump from this goto statement to its label}}
208+
#pragma acc parallel// expected-note{{invalid branch into OpenACC Compute Construct}}
209+
{
210+
LABEL7:{}
211+
}
212+
213+
#pragma acc parallel
214+
LABEL8:{}
215+
#pragma acc parallel// expected-note{{invalid branch out of OpenACC Compute Construct}}
216+
{
217+
goto LABEL8;// expected-error{{cannot jump from this goto statement to its label}}
218+
}
219+
220+
221+
#pragma acc parallel// expected-note{{invalid branch into OpenACC Compute Construct}}
222+
{
223+
LABEL9:{}
224+
}
225+
226+
({goto LABEL9;});// expected-error{{cannot jump from this goto statement to its label}}
227+
228+
#pragma acc parallel// expected-note{{invalid branch out of OpenACC Compute Construct}}
229+
{
230+
({goto LABEL10;});// expected-error{{cannot jump from this goto statement to its label}}
231+
}
232+
233+
LABEL10:{}
234+
235+
({goto LABEL11;});// expected-error{{cannot jump from this goto statement to its label}}
236+
#pragma acc parallel// expected-note{{invalid branch into OpenACC Compute Construct}}
237+
{
238+
LABEL11:{}
239+
}
240+
241+
LABEL12:{}
242+
#pragma acc parallel// expected-note{{invalid branch out of OpenACC Compute Construct}}
243+
{
244+
({goto LABEL12;});// expected-error{{cannot jump from this goto statement to its label}}
245+
}
246+
247+
#pragma acc parallel
248+
{
249+
({goto LABEL13;});
250+
LABEL13:{}
251+
}
252+
253+
#pragma acc parallel
254+
{
255+
LABEL14:{}
256+
({goto LABEL14;});
257+
}
258+
}
259+
260+
void IndirectGoto1() {
261+
void* ptr;
262+
#pragma acc parallel
263+
{
264+
LABEL1:{}
265+
ptr = &&LABEL1;
266+
267+
goto *ptr;
268+
269+
}
270+
}
271+
272+
void IndirectGoto2() {
273+
void* ptr;
274+
LABEL2:{} // #GOTOLBL2
275+
ptr = &&LABEL2;
276+
#pragma acc parallel // #GOTOPAR2
277+
{
278+
// expected-error@+3{{cannot jump from this indirect goto statement to one of its possible targets}}
279+
// expected-note@#GOTOLBL2{{possible target of indirect goto statement}}
280+
// expected-note@#GOTOPAR2{{invalid branch out of OpenACC Compute Construct}}
281+
goto *ptr;
282+
}
283+
}
284+
285+
void IndirectGoto3() {
286+
void* ptr;
287+
#pragma acc parallel // #GOTOPAR3
288+
{
289+
LABEL3:{} // #GOTOLBL3
290+
ptr = &&LABEL3;
291+
}
292+
// expected-error@+3{{cannot jump from this indirect goto statement to one of its possible targets}}
293+
// expected-note@#GOTOLBL3{{possible target of indirect goto statement}}
294+
// expected-note@#GOTOPAR3{{invalid branch into OpenACC Compute Construct}}
295+
goto *ptr;
296+
}
297+
298+
void IndirectGoto4() {
299+
void* ptr;
300+
#pragma acc parallel // #GOTOPAR4
301+
{
302+
LABEL4:{}
303+
ptr = &&LABEL4;
304+
// expected-error@+3{{cannot jump from this indirect goto statement to one of its possible targets}}
305+
// expected-note@#GOTOLBL5{{possible target of indirect goto statement}}
306+
// expected-note@#GOTOPAR4{{invalid branch out of OpenACC Compute Construct}}
307+
goto *ptr;
308+
}
309+
LABEL5:// #GOTOLBL5
310+
311+
ptr=&&LABEL5;
312+
}

0 commit comments

Comments
 (0)