From fee6ed693ce8d76a9d3eb61f1e6b53c4bc054827 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Mon, 7 Jun 2021 13:19:54 +0200 Subject: [PATCH] Introduce if-elseif-else statement. --- test/tools/ossfuzz/SolidityGenerator.cpp | 58 ++++++++++++++++++------ test/tools/ossfuzz/SolidityGenerator.h | 19 +++++++- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/test/tools/ossfuzz/SolidityGenerator.cpp b/test/tools/ossfuzz/SolidityGenerator.cpp index 6c19b3279..54ebe5aeb 100644 --- a/test/tools/ossfuzz/SolidityGenerator.cpp +++ b/test/tools/ossfuzz/SolidityGenerator.cpp @@ -445,27 +445,58 @@ void IfStmtGenerator::setup() addGenerators(std::move(dependsOn)); } -string IfStmtGenerator::visit() +string IfStmtGenerator::conditionalStmt(Condition _cond) { - ostringstream ifStmt; + ostringstream condStmt; ExpressionGenerator exprGen{state}; auto boolType = make_shared(); pair boolTypeName = {boolType, {}}; auto expression = exprGen.rLValueOrLiteral(boolTypeName); - if (expression.has_value()) - ifStmt << indentation() - << "if (" - << expression.value().second - << ")\n"; + solAssert(expression.has_value(), ""); + if (_cond == Condition::IF) + condStmt << indentation() + << "if (" + << expression.value().second + << ")\n"; + else if (_cond == Condition::ELSEIF) + condStmt << indentation() + << "else if (" + << expression.value().second + << ")\n"; else - return "\n"; + condStmt << indentation() + << "else" + << "\n"; // Make sure block stmt generator does not output an unchecked block mutator->generator()->unchecked(false); - ostringstream ifBlock; - ifBlock << visitChildren(); - if (ifBlock.str().empty()) - ifBlock << indentation() << "{ }\n"; - ifStmt << ifBlock.str(); + ostringstream condBlock; + condBlock << visitChildren(); + if (condBlock.str().empty()) + condBlock << indentation() << "{ }\n"; + condStmt << condBlock.str(); + return condStmt.str(); +} + +string IfStmtGenerator::visit() +{ + ostringstream ifStmt; + auto numConditionStmts = uRandDist()->distributionOneToN(s_maxConditionalStmts); + ifStmt << conditionalStmt(Condition::IF); + numConditionStmts--; + solAssert(numConditionStmts >= 0, ""); + while (numConditionStmts > 0) + { + if (numConditionStmts == 1) + { + if (uRandDist()->probable(2)) + ifStmt << conditionalStmt(Condition::ELSEIF); + else + ifStmt << conditionalStmt(Condition::ELSE); + } + else + ifStmt << conditionalStmt(Condition::ELSEIF); + numConditionStmts--; + } return ifStmt.str(); } @@ -523,6 +554,7 @@ string BlockStmtGenerator::visit() { if (nestingTooDeep()) return indentation() + "{ }\n"; + ScopeGuard decDepth([&]() { decrementNestingDepth(); }); incrementNestingDepth(); ostringstream block; if (unchecked() && !m_inUnchecked) diff --git a/test/tools/ossfuzz/SolidityGenerator.h b/test/tools/ossfuzz/SolidityGenerator.h index 72813e117..912c35569 100644 --- a/test/tools/ossfuzz/SolidityGenerator.h +++ b/test/tools/ossfuzz/SolidityGenerator.h @@ -173,7 +173,7 @@ public: bool operator>=(IntegerType const& _rhs) { return this->signedType == _rhs.signedType && - this->numBits >= _rhs.numBits; + this->numBits == _rhs.numBits; } std::string toString() override { @@ -823,6 +823,10 @@ struct ExpressionGenerator { nestingDepth++; } + void decrementNestingDepth() + { + nestingDepth--; + } void resetNestingDepth() { nestingDepth = 0; @@ -1074,12 +1078,23 @@ public: class IfStmtGenerator: public GeneratorBase { public: + enum class Condition + { + IF, + ELSEIF, + ELSE + }; + explicit IfStmtGenerator(SolidityGenerator* _mutator): GeneratorBase(std::move(_mutator)) {} void setup() override; std::string visit() override; std::string name() override { return "If statement generator"; } +private: + std::string conditionalStmt(Condition _cond); + static constexpr size_t s_maxConditionalStmts = 5; + }; class AssignmentStmtGenerator: public GeneratorBase @@ -1160,7 +1175,7 @@ private: bool m_unchecked; bool m_inUnchecked; static constexpr unsigned s_maxStatements = 4; - static constexpr unsigned s_maxNestingDepth = 1; + static constexpr unsigned s_maxNestingDepth = 10; static constexpr size_t s_uncheckedInvProb = 13; };