Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spirv-fuzz: Do not allow Block-decorated structs when adding parameters #3931

Merged
merged 1 commit into from
Oct 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions source/fuzz/fuzzer_pass_add_parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ void FuzzerPassAddParameters::Apply() {
// Compute type candidates for the new parameter.
std::vector<uint32_t> type_candidates;
for (const auto& type_inst : GetIRContext()->module()->GetTypes()) {
const auto* type =
GetIRContext()->get_type_mgr()->GetType(type_inst->result_id());
assert(type && "Type instruction is not registered in the type manager");
if (TransformationAddParameter::IsParameterTypeSupported(*type)) {
if (TransformationAddParameter::IsParameterTypeSupported(
GetIRContext(), type_inst->result_id())) {
type_candidates.push_back(type_inst->result_id());
}
}
Expand Down
56 changes: 31 additions & 25 deletions source/fuzz/transformation_add_parameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ bool TransformationAddParameter::IsApplicable(
}

// The type must be supported.
uint32_t new_parameter_type_id = message_.parameter_type_id();
auto new_parameter_type =
ir_context->get_type_mgr()->GetType(new_parameter_type_id);
if (!new_parameter_type) {
if (ir_context->get_def_use_mgr()->GetDef(message_.parameter_type_id()) ==
nullptr) {
return false;
}
if (!IsParameterTypeSupported(*new_parameter_type)) {
if (!IsParameterTypeSupported(ir_context, message_.parameter_type_id())) {
return false;
}

Expand Down Expand Up @@ -88,7 +86,7 @@ bool TransformationAddParameter::IsApplicable(
}

// Type of every value of the map must be the same for all callers.
if (new_parameter_type_id != value_type_id) {
if (message_.parameter_type_id() != value_type_id) {
return false;
}
}
Expand Down Expand Up @@ -175,32 +173,40 @@ protobufs::Transformation TransformationAddParameter::ToMessage() const {
}

bool TransformationAddParameter::IsParameterTypeSupported(
const opt::analysis::Type& type) {
opt::IRContext* ir_context, uint32_t type_id) {
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3403):
// Think about other type instructions we can add here.
switch (type.kind()) {
case opt::analysis::Type::kBool:
case opt::analysis::Type::kInteger:
case opt::analysis::Type::kFloat:
case opt::analysis::Type::kMatrix:
case opt::analysis::Type::kVector:
opt::Instruction* type_inst = ir_context->get_def_use_mgr()->GetDef(type_id);
switch (type_inst->opcode()) {
case SpvOpTypeBool:
case SpvOpTypeInt:
case SpvOpTypeFloat:
case SpvOpTypeMatrix:
case SpvOpTypeVector:
return true;
case SpvOpTypeArray:
return IsParameterTypeSupported(ir_context,
type_inst->GetSingleWordInOperand(0));
case SpvOpTypeStruct:
if (fuzzerutil::HasBlockOrBufferBlockDecoration(ir_context, type_id)) {
return false;
}
for (uint32_t i = 0; i < type_inst->NumInOperands(); i++) {
if (!IsParameterTypeSupported(ir_context,
type_inst->GetSingleWordInOperand(i))) {
return false;
}
}
return true;
case opt::analysis::Type::kArray:
return IsParameterTypeSupported(*type.AsArray()->element_type());
case opt::analysis::Type::kStruct:
return std::all_of(type.AsStruct()->element_types().begin(),
type.AsStruct()->element_types().end(),
[](const opt::analysis::Type* element_type) {
return IsParameterTypeSupported(*element_type);
});
case opt::analysis::Type::kPointer: {
auto storage_class = type.AsPointer()->storage_class();
case SpvOpTypePointer: {
SpvStorageClass storage_class =
static_cast<SpvStorageClass>(type_inst->GetSingleWordInOperand(0));
switch (storage_class) {
case SpvStorageClassPrivate:
case SpvStorageClassFunction:
case SpvStorageClassWorkgroup: {
auto pointee_type = type.AsPointer()->pointee_type();
return IsParameterTypeSupported(*pointee_type);
return IsParameterTypeSupported(ir_context,
type_inst->GetSingleWordInOperand(1));
}
default:
return false;
Expand Down
3 changes: 2 additions & 1 deletion source/fuzz/transformation_add_parameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ class TransformationAddParameter : public Transformation {

// Returns true if the type of the parameter is supported by this
// transformation.
static bool IsParameterTypeSupported(const opt::analysis::Type& type);
static bool IsParameterTypeSupported(opt::IRContext* ir_context,
uint32_t type_id);

private:
protobufs::TransformationAddParameter message_;
Expand Down