mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9281 from ethereum/fix-6772
Fuzzer: Add a specialized StackTooDeepError Exception that is caught …
This commit is contained in:
commit
ea46636ad2
@ -38,6 +38,7 @@ class Error;
|
|||||||
using ErrorList = std::vector<std::shared_ptr<Error const>>;
|
using ErrorList = std::vector<std::shared_ptr<Error const>>;
|
||||||
|
|
||||||
struct CompilerError: virtual util::Exception {};
|
struct CompilerError: virtual util::Exception {};
|
||||||
|
struct StackTooDeepError: virtual CompilerError {};
|
||||||
struct InternalCompilerError: virtual util::Exception {};
|
struct InternalCompilerError: virtual util::Exception {};
|
||||||
struct FatalError: virtual util::Exception {};
|
struct FatalError: virtual util::Exception {};
|
||||||
struct UnimplementedFeatureError: virtual util::Exception {};
|
struct UnimplementedFeatureError: virtual util::Exception {};
|
||||||
|
@ -226,8 +226,9 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
|
|||||||
else
|
else
|
||||||
solUnimplemented("Copying of type " + _sourceType.toString(false) + " to storage not yet supported.");
|
solUnimplemented("Copying of type " + _sourceType.toString(false) + " to storage not yet supported.");
|
||||||
// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] <source_value>...
|
// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] <source_value>...
|
||||||
solAssert(
|
assertThrow(
|
||||||
2 + byteOffsetSize + sourceBaseType->sizeOnStack() <= 16,
|
2 + byteOffsetSize + sourceBaseType->sizeOnStack() <= 16,
|
||||||
|
StackTooDeepError,
|
||||||
"Stack too deep, try removing local variables."
|
"Stack too deep, try removing local variables."
|
||||||
);
|
);
|
||||||
// fetch target storage reference
|
// fetch target storage reference
|
||||||
|
@ -404,7 +404,7 @@ void CompilerContext::appendInlineAssembly(
|
|||||||
stackDiff -= 1;
|
stackDiff -= 1;
|
||||||
if (stackDiff < 1 || stackDiff > 16)
|
if (stackDiff < 1 || stackDiff > 16)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_identifier.location) <<
|
errinfo_sourceLocation(_identifier.location) <<
|
||||||
util::errinfo_comment("Stack too deep (" + to_string(stackDiff) + "), try removing local variables.")
|
util::errinfo_comment("Stack too deep (" + to_string(stackDiff) + "), try removing local variables.")
|
||||||
);
|
);
|
||||||
|
@ -455,7 +455,11 @@ void CompilerUtils::encodeToMemory(
|
|||||||
// leave end_of_mem as dyn head pointer
|
// leave end_of_mem as dyn head pointer
|
||||||
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
|
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
|
||||||
dynPointers++;
|
dynPointers++;
|
||||||
solAssert((argSize + dynPointers) < 16, "Stack too deep, try using fewer variables.");
|
assertThrow(
|
||||||
|
(argSize + dynPointers) < 16,
|
||||||
|
StackTooDeepError,
|
||||||
|
"Stack too deep, try using fewer variables."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -507,8 +511,9 @@ void CompilerUtils::encodeToMemory(
|
|||||||
if (targetType->isDynamicallySized() && !_copyDynamicDataInPlace)
|
if (targetType->isDynamicallySized() && !_copyDynamicDataInPlace)
|
||||||
{
|
{
|
||||||
// copy tail pointer (=mem_end - mem_start) to memory
|
// copy tail pointer (=mem_end - mem_start) to memory
|
||||||
solAssert(
|
assertThrow(
|
||||||
(2 + dynPointers) <= 16,
|
(2 + dynPointers) <= 16,
|
||||||
|
StackTooDeepError,
|
||||||
"Stack too deep(" + to_string(2 + dynPointers) + "), try using fewer variables."
|
"Stack too deep(" + to_string(2 + dynPointers) + "), try using fewer variables."
|
||||||
);
|
);
|
||||||
m_context << dupInstruction(2 + dynPointers) << Instruction::DUP2;
|
m_context << dupInstruction(2 + dynPointers) << Instruction::DUP2;
|
||||||
@ -1290,7 +1295,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
|
|||||||
// move variable starting from its top end in the stack
|
// move variable starting from its top end in the stack
|
||||||
if (stackPosition - size + 1 > 16)
|
if (stackPosition - size + 1 > 16)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_variable.location()) <<
|
errinfo_sourceLocation(_variable.location()) <<
|
||||||
util::errinfo_comment("Stack too deep, try removing local variables.")
|
util::errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
);
|
);
|
||||||
@ -1300,7 +1305,11 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
|
|||||||
|
|
||||||
void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
|
void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
|
||||||
{
|
{
|
||||||
solAssert(_stackDepth <= 16, "Stack too deep, try removing local variables.");
|
assertThrow(
|
||||||
|
_stackDepth <= 16,
|
||||||
|
StackTooDeepError,
|
||||||
|
"Stack too deep, try removing local variables."
|
||||||
|
);
|
||||||
for (unsigned i = 0; i < _itemSize; ++i)
|
for (unsigned i = 0; i < _itemSize; ++i)
|
||||||
m_context << dupInstruction(_stackDepth);
|
m_context << dupInstruction(_stackDepth);
|
||||||
}
|
}
|
||||||
@ -1322,14 +1331,22 @@ void CompilerUtils::moveIntoStack(unsigned _stackDepth, unsigned _itemSize)
|
|||||||
|
|
||||||
void CompilerUtils::rotateStackUp(unsigned _items)
|
void CompilerUtils::rotateStackUp(unsigned _items)
|
||||||
{
|
{
|
||||||
solAssert(_items - 1 <= 16, "Stack too deep, try removing local variables.");
|
assertThrow(
|
||||||
|
_items - 1 <= 16,
|
||||||
|
StackTooDeepError,
|
||||||
|
"Stack too deep, try removing local variables."
|
||||||
|
);
|
||||||
for (unsigned i = 1; i < _items; ++i)
|
for (unsigned i = 1; i < _items; ++i)
|
||||||
m_context << swapInstruction(_items - i);
|
m_context << swapInstruction(_items - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::rotateStackDown(unsigned _items)
|
void CompilerUtils::rotateStackDown(unsigned _items)
|
||||||
{
|
{
|
||||||
solAssert(_items - 1 <= 16, "Stack too deep, try removing local variables.");
|
assertThrow(
|
||||||
|
_items - 1 <= 16,
|
||||||
|
StackTooDeepError,
|
||||||
|
"Stack too deep, try removing local variables."
|
||||||
|
);
|
||||||
for (unsigned i = 1; i < _items; ++i)
|
for (unsigned i = 1; i < _items; ++i)
|
||||||
m_context << swapInstruction(i);
|
m_context << swapInstruction(i);
|
||||||
}
|
}
|
||||||
|
@ -634,7 +634,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
|
|||||||
|
|
||||||
if (stackLayout.size() > 17)
|
if (stackLayout.size() > 17)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_function.location()) <<
|
errinfo_sourceLocation(_function.location()) <<
|
||||||
errinfo_comment("Stack too deep, try removing local variables.")
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
);
|
);
|
||||||
@ -798,7 +798,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
|||||||
solAssert(variable->type()->sizeOnStack() == 1, "");
|
solAssert(variable->type()->sizeOnStack() == 1, "");
|
||||||
if (stackDiff < 1 || stackDiff > 16)
|
if (stackDiff < 1 || stackDiff > 16)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_inlineAssembly.location()) <<
|
errinfo_sourceLocation(_inlineAssembly.location()) <<
|
||||||
errinfo_comment("Stack too deep, try removing local variables.")
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
);
|
);
|
||||||
@ -831,7 +831,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
|||||||
unsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable) - 1;
|
unsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable) - 1;
|
||||||
if (stackDiff > 16 || stackDiff < 1)
|
if (stackDiff > 16 || stackDiff < 1)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_inlineAssembly.location()) <<
|
errinfo_sourceLocation(_inlineAssembly.location()) <<
|
||||||
errinfo_comment("Stack too deep(" + to_string(stackDiff) + "), try removing local variables.")
|
errinfo_comment("Stack too deep(" + to_string(stackDiff) + "), try removing local variables.")
|
||||||
);
|
);
|
||||||
|
@ -226,7 +226,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
solAssert(retSizeOnStack == utils().sizeOnStack(returnTypes), "");
|
solAssert(retSizeOnStack == utils().sizeOnStack(returnTypes), "");
|
||||||
if (retSizeOnStack > 15)
|
if (retSizeOnStack > 15)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_varDecl.location()) <<
|
errinfo_sourceLocation(_varDecl.location()) <<
|
||||||
errinfo_comment("Stack too deep.")
|
errinfo_comment("Stack too deep.")
|
||||||
);
|
);
|
||||||
@ -308,7 +308,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
{
|
{
|
||||||
if (itemSize + lvalueSize > 16)
|
if (itemSize + lvalueSize > 16)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_assignment.location()) <<
|
errinfo_sourceLocation(_assignment.location()) <<
|
||||||
errinfo_comment("Stack too deep, try removing local variables.")
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
);
|
);
|
||||||
|
@ -47,7 +47,7 @@ void StackVariable::retrieveValue(SourceLocation const& _location, bool) const
|
|||||||
unsigned stackPos = m_context.baseToCurrentStackOffset(m_baseStackOffset);
|
unsigned stackPos = m_context.baseToCurrentStackOffset(m_baseStackOffset);
|
||||||
if (stackPos + 1 > 16) //@todo correct this by fetching earlier or moving to memory
|
if (stackPos + 1 > 16) //@todo correct this by fetching earlier or moving to memory
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_location) <<
|
errinfo_sourceLocation(_location) <<
|
||||||
errinfo_comment("Stack too deep, try removing local variables.")
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
);
|
);
|
||||||
@ -61,7 +61,7 @@ void StackVariable::storeValue(Type const&, SourceLocation const& _location, boo
|
|||||||
unsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset) - m_size + 1;
|
unsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset) - m_size + 1;
|
||||||
if (stackDiff > 16)
|
if (stackDiff > 16)
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
CompilerError() <<
|
StackTooDeepError() <<
|
||||||
errinfo_sourceLocation(_location) <<
|
errinfo_sourceLocation(_location) <<
|
||||||
errinfo_comment("Stack too deep, try removing local variables.")
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
);
|
);
|
||||||
|
@ -218,8 +218,9 @@ void CodeGenerator::assemble(
|
|||||||
}
|
}
|
||||||
catch (StackTooDeepError const& _e)
|
catch (StackTooDeepError const& _e)
|
||||||
{
|
{
|
||||||
yulAssert(
|
assertThrow(
|
||||||
false,
|
false,
|
||||||
|
langutil::StackTooDeepError,
|
||||||
"Stack too deep when compiling inline assembly" +
|
"Stack too deep when compiling inline assembly" +
|
||||||
(_e.comment() ? ": " + *_e.comment() : ".")
|
(_e.comment() ? ": " + *_e.comment() : ".")
|
||||||
);
|
);
|
||||||
|
@ -1242,7 +1242,7 @@ BOOST_AUTO_TEST_CASE(use_stack_optimization)
|
|||||||
BOOST_CHECK(result["errors"][0]["severity"] == "error");
|
BOOST_CHECK(result["errors"][0]["severity"] == "error");
|
||||||
BOOST_REQUIRE(result["errors"][0]["message"].isString());
|
BOOST_REQUIRE(result["errors"][0]["message"].isString());
|
||||||
BOOST_CHECK(result["errors"][0]["message"].asString().find("Stack too deep when compiling inline assembly") != std::string::npos);
|
BOOST_CHECK(result["errors"][0]["message"].asString().find("Stack too deep when compiling inline assembly") != std::string::npos);
|
||||||
BOOST_CHECK(result["errors"][0]["type"] == "YulException");
|
BOOST_CHECK(result["errors"][0]["type"] == "CompilerError");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard)
|
BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard)
|
||||||
|
@ -96,6 +96,9 @@ void FuzzerUtil::testCompiler(string const& _input, bool _optimize)
|
|||||||
catch (UnimplementedFeatureError const&)
|
catch (UnimplementedFeatureError const&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
catch (StackTooDeepError const&)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuzzerUtil::runCompiler(string const& _input, bool _quiet)
|
void FuzzerUtil::runCompiler(string const& _input, bool _quiet)
|
||||||
|
Loading…
Reference in New Issue
Block a user