mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Introduce assignment operations.
This commit is contained in:
parent
7394c60dd5
commit
d56dfcf750
@ -286,16 +286,128 @@ string FunctionState::params(Params _p)
|
|||||||
return "(" + boost::algorithm::join(params, ",") + ")";
|
return "(" + boost::algorithm::join(params, ",") + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssignmentStmtGenerator::AssignOp AssignmentStmtGenerator::assignOp(SolidityTypePtr _type)
|
||||||
|
{
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
SIGNEDINTEGER = 1,
|
||||||
|
UNSIGNEDINTEGER,
|
||||||
|
BOOL,
|
||||||
|
FIXEDBYTES,
|
||||||
|
BYTES,
|
||||||
|
FUNCTION,
|
||||||
|
CONTRACT,
|
||||||
|
ADDRESS
|
||||||
|
};
|
||||||
|
static map<Type, vector<AssignOp>> assignOpLookUp = {
|
||||||
|
{SIGNEDINTEGER, {
|
||||||
|
AssignOp::ASSIGN,
|
||||||
|
AssignOp::ASSIGNBITOR,
|
||||||
|
AssignOp::ASSIGNBITXOR,
|
||||||
|
AssignOp::ASSIGNBITAND,
|
||||||
|
AssignOp::ASSIGNADD,
|
||||||
|
AssignOp::ASSIGNSUB,
|
||||||
|
AssignOp::ASSIGNMUL,
|
||||||
|
AssignOp::ASSIGNDIV,
|
||||||
|
AssignOp::ASSIGNMOD
|
||||||
|
}},
|
||||||
|
{UNSIGNEDINTEGER, {
|
||||||
|
AssignOp::ASSIGN,
|
||||||
|
AssignOp::ASSIGNBITOR,
|
||||||
|
AssignOp::ASSIGNBITXOR,
|
||||||
|
AssignOp::ASSIGNBITAND,
|
||||||
|
AssignOp::ASSIGNSHL,
|
||||||
|
AssignOp::ASSIGNSAR,
|
||||||
|
AssignOp::ASSIGNSHR,
|
||||||
|
AssignOp::ASSIGNADD,
|
||||||
|
AssignOp::ASSIGNSUB,
|
||||||
|
AssignOp::ASSIGNMUL,
|
||||||
|
AssignOp::ASSIGNDIV,
|
||||||
|
AssignOp::ASSIGNMOD
|
||||||
|
}},
|
||||||
|
{FIXEDBYTES, {
|
||||||
|
AssignOp::ASSIGN,
|
||||||
|
AssignOp::ASSIGNBITOR,
|
||||||
|
AssignOp::ASSIGNBITXOR,
|
||||||
|
AssignOp::ASSIGNBITAND
|
||||||
|
}},
|
||||||
|
{BOOL, {AssignOp::ASSIGN}},
|
||||||
|
{BYTES, {AssignOp::ASSIGN}},
|
||||||
|
{FUNCTION, {AssignOp::ASSIGN}},
|
||||||
|
{CONTRACT, {AssignOp::ASSIGN}},
|
||||||
|
{ADDRESS, {AssignOp::ASSIGN}}
|
||||||
|
};
|
||||||
|
vector<AssignOp> possibleOps;
|
||||||
|
if (holds_alternative<shared_ptr<IntegerType>>(_type))
|
||||||
|
{
|
||||||
|
auto t = get<shared_ptr<IntegerType>>(_type);
|
||||||
|
if (t->signedType)
|
||||||
|
possibleOps = assignOpLookUp[SIGNEDINTEGER];
|
||||||
|
else
|
||||||
|
possibleOps = assignOpLookUp[UNSIGNEDINTEGER];
|
||||||
|
}
|
||||||
|
else if (holds_alternative<shared_ptr<FixedBytesType>>(_type))
|
||||||
|
{
|
||||||
|
possibleOps = assignOpLookUp[FIXEDBYTES];
|
||||||
|
}
|
||||||
|
else if (holds_alternative<shared_ptr<BoolType>>(_type) ||
|
||||||
|
holds_alternative<shared_ptr<BytesType>>(_type) ||
|
||||||
|
holds_alternative<shared_ptr<FunctionType>>(_type) ||
|
||||||
|
holds_alternative<shared_ptr<ContractType>>(_type) ||
|
||||||
|
holds_alternative<shared_ptr<AddressType>>(_type)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return AssignOp::ASSIGN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
solAssert(false, "");
|
||||||
|
|
||||||
|
return possibleOps[uRandDist->distributionOneToN(possibleOps.size()) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
string AssignmentStmtGenerator::assignOp(AssignOp _op)
|
||||||
|
{
|
||||||
|
switch (_op)
|
||||||
|
{
|
||||||
|
case AssignOp::ASSIGN:
|
||||||
|
return " = ";
|
||||||
|
case AssignOp::ASSIGNBITOR:
|
||||||
|
return " |= ";
|
||||||
|
case AssignOp::ASSIGNBITXOR:
|
||||||
|
return " ^= ";
|
||||||
|
case AssignOp::ASSIGNBITAND:
|
||||||
|
return " &= ";
|
||||||
|
case AssignOp::ASSIGNSHL:
|
||||||
|
return " <<= ";
|
||||||
|
case AssignOp::ASSIGNSAR:
|
||||||
|
case AssignOp::ASSIGNSHR:
|
||||||
|
return " >>= ";
|
||||||
|
case AssignOp::ASSIGNADD:
|
||||||
|
return " += ";
|
||||||
|
case AssignOp::ASSIGNSUB:
|
||||||
|
return " -= ";
|
||||||
|
case AssignOp::ASSIGNMUL:
|
||||||
|
return " *= ";
|
||||||
|
case AssignOp::ASSIGNDIV:
|
||||||
|
return " /= ";
|
||||||
|
case AssignOp::ASSIGNMOD:
|
||||||
|
return " %= ";
|
||||||
|
default:
|
||||||
|
solAssert(false, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string AssignmentStmtGenerator::visit()
|
string AssignmentStmtGenerator::visit()
|
||||||
{
|
{
|
||||||
ExpressionGenerator exprGen{state};
|
ExpressionGenerator exprGen{state};
|
||||||
auto lhs = exprGen.expression();
|
auto lhs = exprGen.randomLValueExpression();
|
||||||
if (!lhs.has_value())
|
if (!lhs.has_value())
|
||||||
return "\n";
|
return "\n";
|
||||||
auto rhs = exprGen.expression(lhs.value());
|
auto rhs = exprGen.expression(lhs.value());
|
||||||
if (!rhs.has_value())
|
if (!rhs.has_value())
|
||||||
return "\n";
|
return "\n";
|
||||||
return indentation() + lhs.value().second + " = " + rhs.value().second + ";\n";
|
auto operation = assignOp(lhs.value().first);
|
||||||
|
return indentation() + lhs.value().second + assignOp(operation) + rhs.value().second + ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatementGenerator::setup()
|
void StatementGenerator::setup()
|
||||||
@ -425,7 +537,7 @@ void FunctionGenerator::endVisit()
|
|||||||
mutator->generator<BlockStmtGenerator>()->resetNestingDepth();
|
mutator->generator<BlockStmtGenerator>()->resetNestingDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<SolidityTypePtr, string> ExpressionGenerator::randomLValueExpression()
|
optional<pair<SolidityTypePtr, string>> ExpressionGenerator::randomLValueExpression()
|
||||||
{
|
{
|
||||||
LValueExpr exprType = static_cast<LValueExpr>(
|
LValueExpr exprType = static_cast<LValueExpr>(
|
||||||
state->uRandDist->distributionOneToN(static_cast<size_t>(LValueExpr::TYPEMAX) - 1)
|
state->uRandDist->distributionOneToN(static_cast<size_t>(LValueExpr::TYPEMAX) - 1)
|
||||||
@ -444,7 +556,10 @@ pair<SolidityTypePtr, string> ExpressionGenerator::randomLValueExpression()
|
|||||||
liveVariables += scope->variables |
|
liveVariables += scope->variables |
|
||||||
ranges::views::transform([](auto& _item) { return _item; }) |
|
ranges::views::transform([](auto& _item) { return _item; }) |
|
||||||
ranges::to<vector<pair<SolidityTypePtr, string>>>();
|
ranges::to<vector<pair<SolidityTypePtr, string>>>();
|
||||||
return liveVariables[state->uRandDist->distributionOneToN(liveVariables.size()) - 1];
|
if (liveVariables.empty())
|
||||||
|
return nullopt;
|
||||||
|
else
|
||||||
|
return liveVariables[state->uRandDist->distributionOneToN(liveVariables.size()) - 1];
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
solAssert(false, "");
|
solAssert(false, "");
|
||||||
@ -476,15 +591,6 @@ optional<pair<SolidityTypePtr, string>> ExpressionGenerator::lValueExpression(
|
|||||||
return liveTypedVariables[state->uRandDist->distributionOneToN(liveTypedVariables.size()) - 1];
|
return liveTypedVariables[state->uRandDist->distributionOneToN(liveTypedVariables.size()) - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<pair<SolidityTypePtr, string>> ExpressionGenerator::expression()
|
|
||||||
{
|
|
||||||
auto currentFunctionState = state->currentFunctionState();
|
|
||||||
// TODO: Remove this barrier once we support more expression types.
|
|
||||||
if (currentFunctionState->inputs.empty() && currentFunctionState->outputs.empty())
|
|
||||||
return nullopt;
|
|
||||||
return randomLValueExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<SolidityTypePtr, string> ExpressionGenerator::literal(SolidityTypePtr _type)
|
pair<SolidityTypePtr, string> ExpressionGenerator::literal(SolidityTypePtr _type)
|
||||||
{
|
{
|
||||||
string literalValue = visit(LiteralGenerator{state}, _type);
|
string literalValue = visit(LiteralGenerator{state}, _type);
|
||||||
|
@ -755,8 +755,7 @@ struct ExpressionGenerator
|
|||||||
std::pair<SolidityTypePtr, std::string> _typeName
|
std::pair<SolidityTypePtr, std::string> _typeName
|
||||||
);
|
);
|
||||||
std::pair<SolidityTypePtr, std::string> literal(SolidityTypePtr _type);
|
std::pair<SolidityTypePtr, std::string> literal(SolidityTypePtr _type);
|
||||||
std::optional<std::pair<SolidityTypePtr, std::string>> expression();
|
std::optional<std::pair<SolidityTypePtr, std::string>> randomLValueExpression();
|
||||||
std::pair<SolidityTypePtr, std::string> randomLValueExpression();
|
|
||||||
std::optional<std::pair<SolidityTypePtr, std::string>> lValueExpression(
|
std::optional<std::pair<SolidityTypePtr, std::string>> lValueExpression(
|
||||||
std::pair<SolidityTypePtr, std::string> _typeName
|
std::pair<SolidityTypePtr, std::string> _typeName
|
||||||
);
|
);
|
||||||
@ -952,11 +951,30 @@ private:
|
|||||||
class AssignmentStmtGenerator: public GeneratorBase
|
class AssignmentStmtGenerator: public GeneratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum class AssignOp: size_t
|
||||||
|
{
|
||||||
|
ASSIGN = 1,
|
||||||
|
ASSIGNBITOR,
|
||||||
|
ASSIGNBITXOR,
|
||||||
|
ASSIGNBITAND,
|
||||||
|
ASSIGNSHL,
|
||||||
|
ASSIGNSAR,
|
||||||
|
ASSIGNSHR,
|
||||||
|
ASSIGNADD,
|
||||||
|
ASSIGNSUB,
|
||||||
|
ASSIGNMUL,
|
||||||
|
ASSIGNDIV,
|
||||||
|
ASSIGNMOD,
|
||||||
|
ASSIGNMAX
|
||||||
|
};
|
||||||
explicit AssignmentStmtGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
explicit AssignmentStmtGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
||||||
GeneratorBase(std::move(_mutator))
|
GeneratorBase(std::move(_mutator))
|
||||||
{}
|
{}
|
||||||
std::string visit() override;
|
std::string visit() override;
|
||||||
std::string name() override { return "Assignment statement generator"; }
|
std::string name() override { return "Assignment statement generator"; }
|
||||||
|
private:
|
||||||
|
AssignOp assignOp(SolidityTypePtr _type);
|
||||||
|
std::string assignOp(AssignOp _op);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockStmtGenerator: public GeneratorBase
|
class BlockStmtGenerator: public GeneratorBase
|
||||||
@ -1008,7 +1026,7 @@ private:
|
|||||||
bool m_unchecked;
|
bool m_unchecked;
|
||||||
bool m_inUnchecked;
|
bool m_inUnchecked;
|
||||||
static constexpr unsigned s_maxStatements = 4;
|
static constexpr unsigned s_maxStatements = 4;
|
||||||
static constexpr unsigned s_maxNestingDepth = 3;
|
static constexpr unsigned s_maxNestingDepth = 1;
|
||||||
static constexpr size_t s_uncheckedInvProb = 13;
|
static constexpr size_t s_uncheckedInvProb = 13;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user