diff --git a/test/tools/ossfuzz/Generators.h b/test/tools/ossfuzz/Generators.h index 9074c895a..e47794b24 100644 --- a/test/tools/ossfuzz/Generators.h +++ b/test/tools/ossfuzz/Generators.h @@ -41,9 +41,11 @@ * */ #define GENERATORLIST(MACRO, SEP, ENDSEP) \ + MACRO(BlockStmtGenerator) SEP \ MACRO(ContractGenerator) SEP \ MACRO(FunctionGenerator) SEP \ MACRO(ImportGenerator) SEP \ MACRO(PragmaGenerator) SEP \ MACRO(SourceUnitGenerator) SEP \ + MACRO(StatementGenerator) SEP \ MACRO(TestCaseGenerator) ENDSEP diff --git a/test/tools/ossfuzz/SolidityGenerator.cpp b/test/tools/ossfuzz/SolidityGenerator.cpp index 311f8c40e..81e053ba7 100644 --- a/test/tools/ossfuzz/SolidityGenerator.cpp +++ b/test/tools/ossfuzz/SolidityGenerator.cpp @@ -263,6 +263,16 @@ string FunctionState::params(Params _p) return "(" + boost::algorithm::join(params, ",") + ")"; } +string BlockStmtGenerator::visit() +{ + return "\n" + indentation() + "{}\n"; +} + +void FunctionGenerator::setup() +{ + addGenerators({{mutator->generator(), 1}}); +} + string FunctionGenerator::visit() { string visibility; @@ -281,7 +291,7 @@ string FunctionGenerator::visit() state->currentFunctionState()->addOutput(TypeProvider{state}.type()); ostringstream function; - function << indentation(state->indentationLevel) + function << indentation() << "function " << name << state->currentFunctionState()->params(FunctionState::Params::INPUT) @@ -291,7 +301,7 @@ string FunctionGenerator::visit() if (!state->currentFunctionState()->outputs.empty()) function << " returns" << state->currentFunctionState()->params(FunctionState::Params::OUTPUT); - function << " {}\n"; + function << generator()->visit(); return function.str(); } diff --git a/test/tools/ossfuzz/SolidityGenerator.h b/test/tools/ossfuzz/SolidityGenerator.h index 3e2fb789c..9064c793c 100644 --- a/test/tools/ossfuzz/SolidityGenerator.h +++ b/test/tools/ossfuzz/SolidityGenerator.h @@ -648,11 +648,11 @@ struct GeneratorBase endVisit(); return generatedCode; } - /// @returns indentation as string. Each indentation level comprises two - /// whitespace characters. - std::string indentation(unsigned _indentationLevel) + /// @returns current indentation as string. Each indentation level comprises + /// two whitespace characters. + std::string indentation() { - return std::string(_indentationLevel * 2, ' '); + return std::string(state->indentationLevel * 2, ' '); } /// @returns a string representing the generation of /// the Solidity grammar element. @@ -791,6 +791,7 @@ public: {} std::string visit() override; std::string name() override { return "Function generator"; } + void setup() override; /// Sets @name m_freeFunction to @param _freeFunction. void scope(bool _freeFunction) { @@ -800,6 +801,28 @@ private: bool m_freeFunction; static constexpr unsigned s_maxInputs = 4; static constexpr unsigned s_maxOutputs = 4; + static constexpr unsigned s_maxStatements = 5; +}; + +class StatementGenerator: public GeneratorBase +{ +public: + explicit StatementGenerator(std::shared_ptr _mutator): + GeneratorBase(std::move(_mutator)) + {} + void setup() override {} + std::string visit() override { return {}; } + std::string name() override { return "Statement generator"; } +}; + +class BlockStmtGenerator: public GeneratorBase +{ +public: + explicit BlockStmtGenerator(std::shared_ptr _mutator): + GeneratorBase(std::move(_mutator)) + {} + std::string visit() override; + std::string name() override { return "Block statement generator"; } }; class SolidityGenerator: public std::enable_shared_from_this