mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add pop(f()) mutation
This commit is contained in:
parent
cba1f05005
commit
c9da41743e
@ -1192,6 +1192,38 @@ static YulProtoMutator addPopCreate(
|
||||
}
|
||||
);
|
||||
|
||||
/// Add pop(f()) where f() -> r is a user-defined function
|
||||
/// Assumes that f() already exists, if it doesn't this
|
||||
/// turns into pop(constant)
|
||||
static YulProtoMutator addPopUserFunction(
|
||||
Block::descriptor(),
|
||||
[](google::protobuf::Message* _message, unsigned int _seed)
|
||||
{
|
||||
if (_seed % YulProtoMutator::s_normalizedBlockIP == 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << "----------------------------------" << std::endl;
|
||||
std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
std::cout << "YULMUTATOR: Add pop(f()) stmt" << std::endl;
|
||||
#endif
|
||||
auto functioncall = new FunctionCall();
|
||||
functioncall->set_ret(FunctionCall::SINGLE);
|
||||
YulProtoMutator::configureCallArgs(FunctionCall::SINGLE, functioncall, _seed);
|
||||
auto funcExpr = new Expression();
|
||||
funcExpr->set_allocated_func_expr(functioncall);
|
||||
auto popStmt = new PopStmt();
|
||||
popStmt->set_allocated_expr(funcExpr);
|
||||
auto block = static_cast<Block*>(_message);
|
||||
auto stmt = block->add_statements();
|
||||
stmt->set_allocated_pop(popStmt);
|
||||
#ifdef DEBUG
|
||||
std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
std::cout << "----------------------------------" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Literal* YulProtoMutator::intLiteral(unsigned _value)
|
||||
{
|
||||
auto lit = new Literal();
|
||||
@ -1227,12 +1259,20 @@ void YulProtoMutator::configureCall(FunctionCall *_call, unsigned int _seed)
|
||||
auto type = EnumTypeConverter<FunctionCall_Returns>{}.enumFromSeed(_seed);
|
||||
_call->set_ret(type);
|
||||
_call->set_func_index(_seed);
|
||||
configureCallArgs(type, _call, _seed);
|
||||
}
|
||||
|
||||
void YulProtoMutator::configureCallArgs(
|
||||
FunctionCall_Returns _callType,
|
||||
FunctionCall *_call,
|
||||
unsigned _seed
|
||||
)
|
||||
{
|
||||
// Configuration rules:
|
||||
// - In/Out parameters do not need to be configured for zero I/O call
|
||||
// - Single in and zero out parameter needs to be configured for single I/O call
|
||||
// - Four in and no out parameters need to be configured for multidecl call
|
||||
// - Four in and out parameters need to be configured for multiassign call
|
||||
switch (type)
|
||||
// All function calls must configure four input arguments, because
|
||||
// a function of any type may have at most four input arguments.
|
||||
// Out arguments need to be configured only for multi-assign
|
||||
switch (_callType)
|
||||
{
|
||||
case FunctionCall_Returns_MULTIASSIGN:
|
||||
{
|
||||
@ -1250,6 +1290,10 @@ void YulProtoMutator::configureCall(FunctionCall *_call, unsigned int _seed)
|
||||
}
|
||||
BOOST_FALLTHROUGH;
|
||||
case FunctionCall_Returns_MULTIDECL:
|
||||
BOOST_FALLTHROUGH;
|
||||
case FunctionCall_Returns_SINGLE:
|
||||
BOOST_FALLTHROUGH;
|
||||
case FunctionCall_Returns_ZERO:
|
||||
{
|
||||
auto inArg4 = new Expression();
|
||||
auto inRef4 = YulProtoMutator::varRef(_seed * 4);
|
||||
@ -1265,19 +1309,14 @@ void YulProtoMutator::configureCall(FunctionCall *_call, unsigned int _seed)
|
||||
auto inRef2 = YulProtoMutator::varRef(_seed * 2);
|
||||
inArg2->set_allocated_varref(inRef2);
|
||||
_call->set_allocated_in_param2(inArg2);
|
||||
}
|
||||
BOOST_FALLTHROUGH;
|
||||
case FunctionCall_Returns_SINGLE:
|
||||
{
|
||||
|
||||
auto inArg1 = new Expression();
|
||||
auto inRef1 = YulProtoMutator::varRef(_seed);
|
||||
inArg1->set_allocated_varref(inRef1);
|
||||
_call->set_allocated_in_param1(inArg1);
|
||||
}
|
||||
BOOST_FALLTHROUGH;
|
||||
case FunctionCall_Returns_ZERO:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -48,6 +48,17 @@ struct YulProtoMutator
|
||||
/// @param _seed: Pseudo-random unsigned integer
|
||||
static void configureCall(FunctionCall *_call, unsigned _seed);
|
||||
|
||||
/// Configure function call arguments.
|
||||
/// @param _callType: Enum stating type of function call
|
||||
/// i.e., no-return, single-return, multi-decl, or multi-assign.
|
||||
/// @param _call: Pre-allocated protobuf message of FunctionCall type
|
||||
/// @param _seed: Pseudo-random unsigned integer.
|
||||
static void configureCallArgs(
|
||||
FunctionCall_Returns _callType,
|
||||
FunctionCall *_call,
|
||||
unsigned _seed
|
||||
);
|
||||
|
||||
/// Helper type for type matching visitor.
|
||||
template<class T> struct AlwaysFalse: std::false_type {};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user