mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Enable fine grained yul optimizer fuzzing
This commit is contained in:
parent
0b023b893e
commit
b3dd83a20b
@ -74,7 +74,8 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line
|
||||
soltestAssert(m_dialect, "Dialect not set.");
|
||||
|
||||
m_object->analysisInfo = m_analysisInfo;
|
||||
YulOptimizerTestCommon tester(m_object, *m_dialect, m_optimizerStep);
|
||||
YulOptimizerTestCommon tester(m_object, *m_dialect);
|
||||
tester.setStep(m_optimizerStep);
|
||||
|
||||
if (!tester.runStep())
|
||||
{
|
||||
|
@ -66,6 +66,8 @@
|
||||
|
||||
#include <libsolidity/interface/OptimiserSettings.h>
|
||||
|
||||
#include <random>
|
||||
|
||||
using namespace solidity;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::langutil;
|
||||
@ -76,15 +78,13 @@ using namespace std;
|
||||
|
||||
YulOptimizerTestCommon::YulOptimizerTestCommon(
|
||||
shared_ptr<Object> _obj,
|
||||
Dialect const& _dialect,
|
||||
string const& _optimizerStep
|
||||
Dialect const& _dialect
|
||||
)
|
||||
{
|
||||
m_object = _obj;
|
||||
m_ast = m_object->code;
|
||||
m_analysisInfo = m_object->analysisInfo;
|
||||
m_dialect = &_dialect;
|
||||
m_optimizerStep = _optimizerStep;
|
||||
|
||||
m_namedSteps = {
|
||||
{"disambiguator", [&]() { disambiguate(); }},
|
||||
@ -360,6 +360,11 @@ YulOptimizerTestCommon::YulOptimizerTestCommon(
|
||||
};
|
||||
}
|
||||
|
||||
void YulOptimizerTestCommon::setStep(string const& _optimizerStep)
|
||||
{
|
||||
m_optimizerStep = _optimizerStep;
|
||||
}
|
||||
|
||||
bool YulOptimizerTestCommon::runStep()
|
||||
{
|
||||
yulAssert(m_dialect, "Dialect not set.");
|
||||
@ -374,6 +379,31 @@ bool YulOptimizerTestCommon::runStep()
|
||||
return true;
|
||||
}
|
||||
|
||||
string YulOptimizerTestCommon::randomOptimiserStep(unsigned _seed)
|
||||
{
|
||||
std::mt19937 prng(_seed);
|
||||
std::uniform_int_distribution<size_t> dist(1, m_namedSteps.size());
|
||||
size_t idx = dist(prng);
|
||||
size_t count = 1;
|
||||
for (auto &step: m_namedSteps)
|
||||
{
|
||||
if (count == idx)
|
||||
{
|
||||
string optimiserStep = step.first;
|
||||
// Do not fuzz mainFunction or wordSizeTransform
|
||||
// because they do not preserve yul code semantics.
|
||||
if (optimiserStep == "mainFunction" || optimiserStep == "wordSizeTransform")
|
||||
// "Fullsuite" is fuzzed roughly three times more frequently than
|
||||
// other steps because of the filtering in place above.
|
||||
return "fullSuite";
|
||||
else
|
||||
return optimiserStep;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
yulAssert(false, "Optimiser step selection failed.");
|
||||
}
|
||||
|
||||
shared_ptr<Block> YulOptimizerTestCommon::run()
|
||||
{
|
||||
return runStep() ? m_ast : nullptr;
|
||||
|
@ -40,15 +40,22 @@ class YulOptimizerTestCommon
|
||||
public:
|
||||
explicit YulOptimizerTestCommon(
|
||||
std::shared_ptr<Object> _obj,
|
||||
Dialect const& _dialect,
|
||||
std::string const& _optimizerStep
|
||||
Dialect const& _dialect
|
||||
);
|
||||
/// Sets optimiser step to be run to @param
|
||||
/// _optimiserStep.
|
||||
void setStep(std::string const& _optimizerStep);
|
||||
/// Runs chosen optimiser step returning pointer
|
||||
/// to yul AST Block post optimisation.
|
||||
std::shared_ptr<Block> run();
|
||||
/// Runs chosen optimiser step returning true if
|
||||
/// successful, false otherwise.
|
||||
bool runStep();
|
||||
/// Returns the string name of a randomly chosen
|
||||
/// optimiser step.
|
||||
/// @param _seed is an unsigned integer that
|
||||
/// seeds the random selection.
|
||||
std::string randomOptimiserStep(unsigned _seed);
|
||||
private:
|
||||
void disambiguate();
|
||||
void updateContext();
|
||||
|
@ -76,7 +76,12 @@ if (OSSFUZZ)
|
||||
target_link_libraries(strictasm_assembly_ossfuzz PRIVATE yul)
|
||||
set_target_properties(strictasm_assembly_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
|
||||
add_executable(yul_proto_ossfuzz yulProtoFuzzer.cpp protoToYul.cpp yulProto.pb.cc)
|
||||
add_executable(yul_proto_ossfuzz
|
||||
yulProtoFuzzer.cpp
|
||||
protoToYul.cpp
|
||||
yulProto.pb.cc
|
||||
../../libyul/YulOptimizerTestCommon.cpp
|
||||
)
|
||||
target_include_directories(yul_proto_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
|
||||
target_link_libraries(yul_proto_ossfuzz PRIVATE yul
|
||||
protobuf-mutator-libfuzzer.a
|
||||
@ -86,7 +91,14 @@ if (OSSFUZZ)
|
||||
set_target_properties(yul_proto_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
target_compile_options(yul_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion -Wno-suggest-destructor-override -Wno-inconsistent-missing-destructor-override)
|
||||
|
||||
add_executable(yul_proto_diff_ossfuzz yulProto_diff_ossfuzz.cpp yulFuzzerCommon.cpp protoToYul.cpp yulProto.pb.cc)
|
||||
add_executable(
|
||||
yul_proto_diff_ossfuzz
|
||||
yulProto_diff_ossfuzz.cpp
|
||||
yulFuzzerCommon.cpp
|
||||
protoToYul.cpp
|
||||
yulProto.pb.cc
|
||||
../../libyul/YulOptimizerTestCommon.cpp
|
||||
)
|
||||
target_include_directories(yul_proto_diff_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
|
||||
target_link_libraries(yul_proto_diff_ossfuzz PRIVATE yul
|
||||
yulInterpreter
|
||||
@ -103,6 +115,7 @@ if (OSSFUZZ)
|
||||
protoToYul.cpp
|
||||
yulProto.pb.cc
|
||||
protomutators/YulProtoMutator.cpp
|
||||
../../libyul/YulOptimizerTestCommon.cpp
|
||||
)
|
||||
target_include_directories(yul_proto_diff_custom_mutate_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
|
||||
target_link_libraries(yul_proto_diff_custom_mutate_ossfuzz PRIVATE yul
|
||||
|
@ -64,7 +64,6 @@ public:
|
||||
{
|
||||
return m_evmVersion;
|
||||
}
|
||||
|
||||
private:
|
||||
void visit(BinaryOp const&);
|
||||
|
||||
|
@ -415,6 +415,7 @@ message Program {
|
||||
Object obj = 2;
|
||||
}
|
||||
required Version ver = 3;
|
||||
required uint32 step = 4;
|
||||
}
|
||||
|
||||
package solidity.yul.test.yul_fuzzer;
|
||||
|
@ -19,16 +19,24 @@
|
||||
#include <fstream>
|
||||
|
||||
#include <test/tools/ossfuzz/yulProto.pb.h>
|
||||
#include <test/tools/fuzzer_common.h>
|
||||
#include <test/tools/ossfuzz/protoToYul.h>
|
||||
#include <src/libfuzzer/libfuzzer_macro.h>
|
||||
|
||||
#include <test/tools/fuzzer_common.h>
|
||||
|
||||
#include <test/libyul/YulOptimizerTestCommon.h>
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
#include <libyul/Exceptions.h>
|
||||
|
||||
#include <libyul/backends/evm/EVMDialect.h>
|
||||
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
|
||||
#include <src/libfuzzer/libfuzzer_macro.h>
|
||||
|
||||
using namespace solidity;
|
||||
using namespace solidity::yul;
|
||||
using namespace solidity::yul::test;
|
||||
using namespace solidity::yul::test::yul_fuzzer;
|
||||
using namespace solidity::langutil;
|
||||
using namespace std;
|
||||
@ -69,5 +77,11 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
yulAssert(false, "Proto fuzzer generated malformed program");
|
||||
|
||||
// Optimize
|
||||
stack.optimize();
|
||||
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.");
|
||||
}
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include <test/tools/ossfuzz/yulProto.pb.h>
|
||||
#include <test/tools/fuzzer_common.h>
|
||||
#include <test/tools/ossfuzz/protoToYul.h>
|
||||
|
||||
#include <test/libyul/YulOptimizerTestCommon.h>
|
||||
|
||||
#include <src/libfuzzer/libfuzzer_macro.h>
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
@ -104,10 +107,16 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
)
|
||||
return;
|
||||
|
||||
stack.optimize();
|
||||
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.");
|
||||
termReason = yulFuzzerUtil::interpret(
|
||||
os2,
|
||||
stack.parserResult()->code,
|
||||
astBlock,
|
||||
EVMDialect::strictAssemblyForEVMObjects(version)
|
||||
);
|
||||
if (
|
||||
|
Loading…
Reference in New Issue
Block a user