Skip to content

Commit 6dacc38

Browse files
committed
[OpenACC] Properly ignore side-effects in clause arguments
The OpenACC standard makes depending on side effects to be effectively UB, so this patch ensures we handle them reaonably by making it a potentially evaluated context, and ignoring cleanups.
1 parent cb3eb06 commit 6dacc38

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,10 @@ ExprResult SemaOpenACC::CheckReductionVar(Expr *VarExpr) {
12101210

12111211
void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
12121212
SourceLocation DirLoc) {
1213+
// Start an evaluation context to parse the clause arguments on.
1214+
SemaRef.PushExpressionEvaluationContext(
1215+
Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
1216+
12131217
switch (K) {
12141218
case OpenACCDirectiveKind::Invalid:
12151219
// Nothing to do here, an invalid kind has nothing we can check here. We
@@ -1626,6 +1630,8 @@ ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
16261630

16271631
bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
16281632
SourceLocation StartLoc) {
1633+
SemaRef.DiscardCleanupsInEvaluationContext();
1634+
SemaRef.PopExpressionEvaluationContext();
16291635
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
16301636
}
16311637

@@ -1649,6 +1655,7 @@ StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K,
16491655
ParentlessLoopConstructs);
16501656

16511657
ParentlessLoopConstructs.clear();
1658+
16521659
return ComputeConstruct;
16531660
}
16541661
case OpenACCDirectiveKind::Loop: {
@@ -1704,6 +1711,11 @@ StmtResult SemaOpenACC::ActOnAssociatedStmt(SourceLocation DirectiveLoc,
17041711

17051712
bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
17061713
SourceLocation StartLoc) {
1714+
// OpenCC3.3 2.1 (line 889)
1715+
// A program must not depend on the order of evaluation of expressions in
1716+
// clause arguments or on any side effects of the evaluations.
1717+
SemaRef.DiscardCleanupsInEvaluationContext();
1718+
SemaRef.PopExpressionEvaluationContext();
17071719
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
17081720
}
17091721

clang/test/SemaOpenACC/compute-construct-ast.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,26 @@ struct S {
117117
void use() {
118118
TemplFunc<S>();
119119
}
120-
#endif
121120

121+
struct HasCtor { HasCtor(); operator int(); ~HasCtor();};
122+
123+
void useCtorType() {
124+
// CHECK-LABEL: useCtorType
125+
// CHECK-NEXT: CompoundStmt
126+
127+
#pragma acc kernels num_workers(HasCtor{})
128+
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} kernels
129+
// CHECK-NEXT: num_workers clause
130+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <UserDefinedConversion>
131+
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'int'
132+
// CHECK-NEXT: MemberExpr{{.*}}.operator int
133+
// CHECK-NEXT: MaterializeTemporaryExpr{{.*}}'HasCtor'
134+
// CHECK-NEXT: CXXBindTemporaryExpr{{.*}}'HasCtor'
135+
// CHECK-NEXT: CXXTemporaryObjectExpr{{.*}}'HasCtor'
136+
137+
while(true);
138+
// CHECK-NEXT: WhileStmt
139+
// CHECK-NEXT: CXXBoolLiteralExpr
140+
// CHECK-NEXT: NullStmt
141+
}
142+
#endif

0 commit comments

Comments
 (0)