mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9357 from ethereum/fix-9356
Disable more than one reference to a variable on the LHS of a tuple a…
This commit is contained in:
commit
8b52985744
@ -178,6 +178,14 @@ bool ProtoConverter::functionCallNotPossible(FunctionCall_Returns _type)
|
||||
(_type == FunctionCall::MULTIASSIGN && !varDeclAvailable());
|
||||
}
|
||||
|
||||
unsigned ProtoConverter::numVarsInScope()
|
||||
{
|
||||
if (m_inFunctionDef)
|
||||
return m_currentFuncVars.size();
|
||||
else
|
||||
return m_currentGlobalVars.size();
|
||||
}
|
||||
|
||||
void ProtoConverter::visit(VarRef const& _x)
|
||||
{
|
||||
if (m_inFunctionDef)
|
||||
@ -830,18 +838,18 @@ void ProtoConverter::visitFunctionInputParams(FunctionCall const& _x, unsigned _
|
||||
case 4:
|
||||
visit(_x.in_param4());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 3:
|
||||
visit(_x.in_param3());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 2:
|
||||
visit(_x.in_param2());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 1:
|
||||
visit(_x.in_param1());
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
@ -966,23 +974,43 @@ void ProtoConverter::visit(FunctionCall const& _x)
|
||||
"Proto fuzzer: Function call with too many output params encountered."
|
||||
);
|
||||
|
||||
// Return early if numOutParams > number of available variables
|
||||
if (numOutParams > numVarsInScope())
|
||||
return;
|
||||
|
||||
// Copy variables in scope in order to prevent repeated references
|
||||
vector<string> variables;
|
||||
if (m_inFunctionDef)
|
||||
for (auto var: m_currentFuncVars)
|
||||
variables.push_back(*var);
|
||||
else
|
||||
for (auto var: m_currentGlobalVars)
|
||||
variables.push_back(*var);
|
||||
|
||||
auto refVar = [](vector<string>& _var, unsigned _rand, bool _comma = true) -> string
|
||||
{
|
||||
auto index = _rand % _var.size();
|
||||
string ref = _var[index];
|
||||
_var.erase(_var.begin() + index);
|
||||
if (_comma)
|
||||
ref += ", ";
|
||||
return ref;
|
||||
};
|
||||
|
||||
// Convert LHS of multi assignment
|
||||
// We reverse the order of out param visits since the order does not matter.
|
||||
// This helps reduce the size of this switch statement.
|
||||
switch (numOutParams)
|
||||
{
|
||||
case 4:
|
||||
visit(_x.out_param4());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
m_output << refVar(variables, _x.out_param4().varnum());
|
||||
[[fallthrough]];
|
||||
case 3:
|
||||
visit(_x.out_param3());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
m_output << refVar(variables, _x.out_param3().varnum());
|
||||
[[fallthrough]];
|
||||
case 2:
|
||||
visit(_x.out_param2());
|
||||
m_output << ", ";
|
||||
visit(_x.out_param1());
|
||||
m_output << refVar(variables, _x.out_param2().varnum());
|
||||
m_output << refVar(variables, _x.out_param1().varnum(), false);
|
||||
break;
|
||||
default:
|
||||
yulAssert(false, "Proto fuzzer: Function call with too many or too few input parameters.");
|
||||
|
@ -120,6 +120,8 @@ private:
|
||||
void closeFunctionScope();
|
||||
/// Adds @a _vars to current scope
|
||||
void addVarsToScope(std::vector<std::string> const& _vars);
|
||||
/// @returns number of variables that are in scope
|
||||
unsigned numVarsInScope();
|
||||
|
||||
std::string createHex(std::string const& _hexBytes);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user