1717#include " source/fuzz/fuzzer_context.h"
1818#include " source/fuzz/fuzzer_util.h"
1919#include " source/fuzz/instruction_descriptor.h"
20+ #include " source/fuzz/transformation_add_global_variable.h"
21+ #include " source/fuzz/transformation_add_local_variable.h"
2022#include " source/fuzz/transformation_add_parameter.h"
2123
2224namespace spvtools {
@@ -38,8 +40,17 @@ void FuzzerPassAddParameters::Apply() {
3840 const auto * type =
3941 GetIRContext ()->get_type_mgr ()->GetType (type_inst->result_id ());
4042 assert (type && " Type instruction is not registered in the type manager" );
43+
4144 if (TransformationAddParameter::IsParameterTypeSupported (*type)) {
4245 type_candidates.push_back (type_inst->result_id ());
46+ } else if (type->kind () == opt::analysis::Type::kPointer ) {
47+ // Pointer types with global scope are allowed.
48+ SpvStorageClass storage_class =
49+ fuzzerutil::GetStorageClassFromPointerType (GetIRContext (),
50+ type_inst->result_id ());
51+ if (storage_class == SpvStorageClassPrivate) {
52+ type_candidates.push_back (type_inst->result_id ());
53+ }
4354 }
4455 }
4556
@@ -70,14 +81,35 @@ void FuzzerPassAddParameters::Apply() {
7081 GetFuzzerContext ()->GetRandomNumberOfNewParameters (
7182 GetNumberOfParameters (function));
7283 for (uint32_t i = 0 ; i < num_new_parameters; ++i) {
73- ApplyTransformation (TransformationAddParameter (
74- function.result_id (), GetFuzzerContext ()->GetFreshId (),
75- // We mark the constant as irrelevant so that we can replace it with a
76- // more interesting value later.
77- FindOrCreateZeroConstant (
78- type_candidates[GetFuzzerContext ()->RandomIndex (type_candidates)],
79- true ),
80- GetFuzzerContext ()->GetFreshId ()));
84+ uint32_t current_type_id =
85+ type_candidates[GetFuzzerContext ()->RandomIndex (type_candidates)];
86+ auto current_type =
87+ GetIRContext ()->get_type_mgr ()->GetType (current_type_id);
88+ auto current_instr =
89+ GetIRContext ()->get_def_use_mgr ()->GetDef (current_type_id);
90+
91+ if (current_type->kind () == opt::analysis::Type::kPointer ) {
92+ // Make sure there exists at least one variable with the current pointer
93+ // type.
94+ uint32_t initializer_id =
95+ FindOrCreateZeroConstant (current_type_id, true );
96+ ApplyTransformation (TransformationAddGlobalVariable (
97+ GetFuzzerContext ()->GetFreshId (), current_instr->type_id (),
98+ SpvStorageClassPrivate,
99+ FindOrCreateZeroConstant (current_type_id, true ), true ));
100+
101+ // Add parameter with the used initializer_id.
102+ ApplyTransformation (TransformationAddParameter (
103+ function.result_id (), GetFuzzerContext ()->GetFreshId (),
104+ initializer_id, GetFuzzerContext ()->GetFreshId ()));
105+ } else {
106+ ApplyTransformation (TransformationAddParameter (
107+ function.result_id (), GetFuzzerContext ()->GetFreshId (),
108+ // We mark the constant as irrelevant so that we can replace it with
109+ // a more interesting value later.
110+ FindOrCreateZeroConstant (current_type_id, true ),
111+ GetFuzzerContext ()->GetFreshId ()));
112+ }
81113 }
82114 }
83115}
0 commit comments