mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-03 08:02:41 +00:00
[OpenCL] Check for invalid kernel arguments in array types
Summary: OpenCL specification forbids use of several types as kernel arguments. This patch improves existing diagnostic to look through arrays. Patch by: Andrew Savonichev Reviewers: Anastasia, yaxunl Subscribers: yaxunl, Anastasia, cfe-commits Differential Revision: https://reviews.llvm.org/D49723 llvm-svn: 338427
This commit is contained in:
parent
e1f3062100
commit
3b238ed662
@ -8079,6 +8079,15 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) {
|
||||
if (PT->isRecordType())
|
||||
return RecordKernelParam;
|
||||
|
||||
// Look into an array argument to check if it has a forbidden type.
|
||||
if (PT->isArrayType()) {
|
||||
const Type *UnderlyingTy = PT->getPointeeOrArrayElementType();
|
||||
// Call ourself to check an underlying type of an array. Since the
|
||||
// getPointeeOrArrayElementType returns an innermost type which is not an
|
||||
// array, this recusive call only happens once.
|
||||
return getOpenCLKernelParameterType(S, QualType(UnderlyingTy, 0));
|
||||
}
|
||||
|
||||
return ValidKernelParam;
|
||||
}
|
||||
|
||||
@ -8146,9 +8155,14 @@ static void checkIsValidOpenCLKernelParameter(
|
||||
SmallVector<const FieldDecl *, 4> HistoryStack;
|
||||
HistoryStack.push_back(nullptr);
|
||||
|
||||
const RecordDecl *PD = PT->castAs<RecordType>()->getDecl();
|
||||
VisitStack.push_back(PD);
|
||||
// At this point we already handled everything except of a RecordType or
|
||||
// an ArrayType of a RecordType.
|
||||
assert((PT->isArrayType() || PT->isRecordType()) && "Unexpected type.");
|
||||
const RecordType *RecTy =
|
||||
PT->getPointeeOrArrayElementType()->getAs<RecordType>();
|
||||
const RecordDecl *OrigRecDecl = RecTy->getDecl();
|
||||
|
||||
VisitStack.push_back(RecTy->getDecl());
|
||||
assert(VisitStack.back() && "First decl null?");
|
||||
|
||||
do {
|
||||
@ -8167,7 +8181,15 @@ static void checkIsValidOpenCLKernelParameter(
|
||||
const RecordDecl *RD;
|
||||
if (const FieldDecl *Field = dyn_cast<FieldDecl>(Next)) {
|
||||
HistoryStack.push_back(Field);
|
||||
RD = Field->getType()->castAs<RecordType>()->getDecl();
|
||||
|
||||
QualType FieldTy = Field->getType();
|
||||
// Other field types (known to be valid or invalid) are handled while we
|
||||
// walk around RecordDecl::fields().
|
||||
assert((FieldTy->isArrayType() || FieldTy->isRecordType()) &&
|
||||
"Unexpected type.");
|
||||
const Type *FieldRecTy = FieldTy->getPointeeOrArrayElementType();
|
||||
|
||||
RD = FieldRecTy->castAs<RecordType>()->getDecl();
|
||||
} else {
|
||||
RD = cast<RecordDecl>(Next);
|
||||
}
|
||||
@ -8204,8 +8226,8 @@ static void checkIsValidOpenCLKernelParameter(
|
||||
S.Diag(Param->getLocation(), diag::err_bad_kernel_param_type) << PT;
|
||||
}
|
||||
|
||||
S.Diag(PD->getLocation(), diag::note_within_field_of_type)
|
||||
<< PD->getDeclName();
|
||||
S.Diag(OrigRecDecl->getLocation(), diag::note_within_field_of_type)
|
||||
<< OrigRecDecl->getDeclName();
|
||||
|
||||
// We have an error, now let's go back up through history and show where
|
||||
// the offending field came from
|
||||
|
@ -136,3 +136,16 @@ struct AlsoUser // expected-note{{within field of type 'AlsoUser' declared here}
|
||||
};
|
||||
|
||||
kernel void pointer_in_nested_struct_arg_2(struct Valid valid, struct NestedPointer arg, struct AlsoUser also) { } // expected-error 2 {{struct kernel parameters may not contain pointers}}
|
||||
|
||||
struct ArrayOfPtr // expected-note{{within field of type 'ArrayOfPtr' declared here}}
|
||||
{
|
||||
float *arr[3]; // expected-note{{field of illegal type 'float *[3]' declared here}}
|
||||
// expected-note@-1{{field of illegal type 'float *[3]' declared here}}
|
||||
};
|
||||
kernel void array_of_ptr(struct ArrayOfPtr arr) {} // expected-error{{struct kernel parameters may not contain pointers}}
|
||||
|
||||
struct ArrayOfStruct // expected-note{{within field of type 'ArrayOfStruct' declared here}}
|
||||
{
|
||||
struct ArrayOfPtr arr[3]; // expected-note{{within field of type 'struct ArrayOfPtr [3]' declared here}}
|
||||
};
|
||||
kernel void array_of_struct(struct ArrayOfStruct arr) {} // expected-error{{struct kernel parameters may not contain pointers}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user