#include "gtest/gtest.h"
#include "source/fuzz/fuzzer_pass_add_opphi_synonyms.h"
#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/pseudo_random_generator.h"
#include "test/fuzz/fuzz_test_util.h"
namespace spvtools {
namespace fuzz {
namespace {
class FuzzerPassMock : public FuzzerPass {
public:
FuzzerPassMock(opt::IRContext* ir_context,
TransformationContext* transformation_context,
FuzzerContext* fuzzer_context,
protobufs::TransformationSequence* transformations)
: FuzzerPass(ir_context, transformation_context, fuzzer_context,
transformations, false) {}
~FuzzerPassMock() override = default;
const std::unordered_set<uint32_t>& GetReachedInstructions() const {
return reached_ids_;
}
void Apply() override {
ForEachInstructionWithInstructionDescriptor(
[this](opt::Function* , opt::BasicBlock* ,
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& ) {
if (inst_it->result_id()) {
reached_ids_.insert(inst_it->result_id());
}
});
}
private:
std::unordered_set<uint32_t> reached_ids_;
};
TEST(FuzzerPassTest, ForEachInstructionWithInstructionDescriptor) {
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%4 = OpFunction %2 None %3
%5 = OpLabel
%7 = OpUndef %6
OpReturn
%8 = OpLabel
%9 = OpUndef %6
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
spvtools::ValidatorOptions validator_options;
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
const auto* dominator_analysis =
context->GetDominatorAnalysis(context->GetFunction(4));
ASSERT_TRUE(dominator_analysis->IsReachable(5));
ASSERT_FALSE(dominator_analysis->IsReachable(8));
FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
false);
protobufs::TransformationSequence transformations;
FuzzerPassMock fuzzer_pass_mock(context.get(), &transformation_context,
&fuzzer_context, &transformations);
fuzzer_pass_mock.Apply();
ASSERT_TRUE(fuzzer_pass_mock.GetReachedInstructions().count(7));
ASSERT_FALSE(fuzzer_pass_mock.GetReachedInstructions().count(9));
}
} } }