#include <fstream>
#include <test/tools/ossfuzz/yulProto.pb.h>
#include <test/tools/ossfuzz/protoToYul.h>
#include <test/tools/fuzzer_common.h>
#include <test/libyul/YulOptimizerTestCommon.h>
#include <libyul/YulStack.h>
#include <libyul/Exceptions.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/EVMVersion.h>
#include <src/libfuzzer/libfuzzer_macro.h>
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::yul;
using namespace solidity::yul::test;
using namespace solidity::yul::test::yul_fuzzer;
using namespace std;
DEFINE_PROTO_FUZZER(Program const& _input)
{
ProtoConverter converter;
string yul_source = converter.programToString(_input);
EVMVersion version = converter.version();
if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH"))
{
ofstream of(dump_path);
of.write(yul_source.data(), static_cast<streamsize>(yul_source.size()));
}
if (yul_source.size() > 1200)
return;
YulStringRepository::reset();
YulStack stack(
version,
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::full(),
DebugInfoSelection::All()
);
if (
!stack.parseAndAnalyze("source", yul_source) ||
!stack.parserResult()->code ||
!stack.parserResult()->analysisInfo ||
Error::containsErrors(stack.errors())
)
yulAssert(false, "Proto fuzzer generated malformed program");
YulOptimizerTestCommon optimizerTest(
stack.parserResult(),
EVMDialect::strictAssemblyForEVMObjects(version)
);
optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step()));
shared_ptr<solidity::yul::Block> astBlock = optimizerTest.run();
yulAssert(astBlock != nullptr, "Optimiser error.");
}