Skip to content

Commit 26dde15

Browse files
committed
[OpenACC] Add warning for VLAs in a private/firstprivate clause
private/firstprivate typically do copy operations, however copying a VLA isn't really possible. This patch introduces a warning to alert the person that this copy isn't happening correctly. As a future direction, we MIGHT consider doing additional work to make sure they are initialized/copied/deleted/etc correctly.
1 parent c2eddec commit 26dde15

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13531,6 +13531,11 @@ def err_acc_invalid_default_type
1353113531
def err_acc_device_type_multiple_archs
1353213532
: Error<"OpenACC 'device_type' clause on a 'set' construct only permits "
1353313533
"one architecture">;
13534+
def warn_acc_var_referenced_non_const_array
13535+
: Warning<"variable of array type %0 referenced in OpenACC '%1' clause "
13536+
"does not have constant bounds; initialization will happen after "
13537+
"decay to pointer">,
13538+
InGroup<DiagGroup<"openacc-var-non-const-array">>;
1353413539
def warn_acc_var_referenced_lacks_op
1353513540
: Warning<"variable of type %0 referenced in OpenACC '%1' clause does not "
1353613541
"have a %enum_select<AccVarReferencedReason>{%DefCtor{default "

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,17 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
646646
if (auto *RefTy = InnerTy->getAs<ReferenceType>())
647647
InnerTy = RefTy->getPointeeType();
648648

649-
if (auto *ArrTy = InnerTy->getAsArrayTypeUnsafe())
649+
if (auto *ArrTy = InnerTy->getAsArrayTypeUnsafe()) {
650+
// Non constant arrays decay to 'pointer', so warn and return that we're
651+
// successful.
652+
if (!ArrTy->isConstantArrayType()) {
653+
S.Diag(InnerLoc, clang::diag::warn_acc_var_referenced_non_const_array)
654+
<< InnerTy << CK;
655+
return VarExpr;
656+
}
657+
650658
return CheckVarType(S, CK, VarExpr, InnerLoc, ArrTy->getElementType());
659+
}
651660

652661
auto *RD = InnerTy->getAsCXXRecordDecl();
653662

clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,20 @@ void firstprivate_arrays() {
275275
#pragma acc parallel firstprivate(UDCopyArr)
276276
;
277277
}
278+
279+
template<unsigned I>
280+
void non_const_array_templ() {
281+
int CArr[I];
282+
283+
#pragma acc parallel firstprivate(CArr)
284+
;
285+
}
286+
287+
void non_const_arrays(int I) {
288+
non_const_array_templ<5>();
289+
290+
int NCArr[I];
291+
// expected-warning@+1{{variable of array type 'int[I]' referenced in OpenACC 'firstprivate' clause does not have constant bounds; initialization will happen after decay to pointer}}
292+
#pragma acc parallel firstprivate(NCArr)
293+
;
294+
}

clang/test/SemaOpenACC/sub-array.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ void Func(int i, int j) {
6161
#pragma acc parallel private(ptr[3:])
6262
while (true);
6363

64-
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}}
64+
// expected-error@+2{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}}
65+
// expected-warning@+1{{variable of array type 'int[i]' referenced in OpenACC 'private' clause does not have constant bounds; initialization will happen after decay to pointer}}
6566
#pragma acc parallel private(VLA[3:])
6667
while (true);
6768

6869
#pragma acc parallel private(ptr[:3])
6970
while (true);
7071

72+
// expected-warning@+1{{variable of array type 'int[i]' referenced in OpenACC 'private' clause does not have constant bounds; initialization will happen after decay to pointer}}
7173
#pragma acc parallel private(VLA[:3])
7274
while (true);
7375

@@ -159,11 +161,13 @@ void Templ(int i){
159161
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
160162
#pragma acc parallel private(ptr[Conv:])
161163
while (true);
162-
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}}
164+
// expected-error@+2{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}}
165+
// expected-warning@+1{{variable of array type 'int[i]' referenced in OpenACC 'private' clause does not have constant bounds; initialization will happen after decay to pointer}}
163166
#pragma acc parallel private(VLA[Conv:])
164167
while (true);
165168
#pragma acc parallel private(ptr[:Conv])
166169
while (true);
170+
// expected-warning@+1{{variable of array type 'int[i]' referenced in OpenACC 'private' clause does not have constant bounds; initialization will happen after decay to pointer}}
167171
#pragma acc parallel private(VLA[:Conv])
168172
while (true);
169173

0 commit comments

Comments
 (0)