Added assertion and tests suggestions

This commit is contained in:
Leonardo Alt 2018-07-10 18:39:26 +02:00
parent b750ca9741
commit 0c5e0e0d59
4 changed files with 30 additions and 8 deletions

View File

@ -128,6 +128,8 @@ void CompilerContext::addVariable(VariableDeclaration const& _declaration,
{ {
solAssert(m_asm->deposit() >= 0 && unsigned(m_asm->deposit()) >= _offsetToCurrent, ""); solAssert(m_asm->deposit() >= 0 && unsigned(m_asm->deposit()) >= _offsetToCurrent, "");
unsigned sizeOnStack = _declaration.annotation().type->sizeOnStack(); unsigned sizeOnStack = _declaration.annotation().type->sizeOnStack();
// Variables should not have stack size other than [1, 2],
// but that might change when new types are introduced.
solAssert(sizeOnStack == 1 || sizeOnStack == 2, ""); solAssert(sizeOnStack == 1 || sizeOnStack == 2, "");
m_localVariables[&_declaration].push_back(unsigned(m_asm->deposit()) - _offsetToCurrent); m_localVariables[&_declaration].push_back(unsigned(m_asm->deposit()) - _offsetToCurrent);
} }
@ -146,6 +148,7 @@ void CompilerContext::removeVariablesAboveStackHeight(unsigned _stackHeight)
for (auto _var: m_localVariables) for (auto _var: m_localVariables)
{ {
solAssert(!_var.second.empty(), ""); solAssert(!_var.second.empty(), "");
solAssert(_var.second.back() <= stackHeight(), "");
if (_var.second.back() >= _stackHeight) if (_var.second.back() >= _stackHeight)
toRemove.push_back(_var.first); toRemove.push_back(_var.first);
} }
@ -153,6 +156,11 @@ void CompilerContext::removeVariablesAboveStackHeight(unsigned _stackHeight)
removeVariable(*_var); removeVariable(*_var);
} }
unsigned CompilerContext::numberOfLocalVariables() const
{
return m_localVariables.size();
}
eth::Assembly const& CompilerContext::compiledContract(const ContractDefinition& _contract) const eth::Assembly const& CompilerContext::compiledContract(const ContractDefinition& _contract) const
{ {
auto ret = m_compiledContracts.find(&_contract); auto ret = m_compiledContracts.find(&_contract);

View File

@ -74,6 +74,8 @@ public:
void removeVariable(Declaration const& _declaration); void removeVariable(Declaration const& _declaration);
/// Removes all local variables currently allocated above _stackHeight. /// Removes all local variables currently allocated above _stackHeight.
void removeVariablesAboveStackHeight(unsigned _stackHeight); void removeVariablesAboveStackHeight(unsigned _stackHeight);
/// Returns the number of currently allocated local variables.
unsigned numberOfLocalVariables() const;
void setCompiledContracts(std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts) { m_compiledContracts = _contracts; } void setCompiledContracts(std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts) { m_compiledContracts = _contracts; }
eth::Assembly const& compiledContract(ContractDefinition const& _contract) const; eth::Assembly const& compiledContract(ContractDefinition const& _contract) const;

View File

@ -498,8 +498,12 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
m_context.adjustStackOffset(-(int)c_returnValuesSize); m_context.adjustStackOffset(-(int)c_returnValuesSize);
/// The constructor and the fallback function doesn't to jump out. /// The constructor and the fallback function doesn't to jump out.
if (!_function.isConstructor() && !_function.isFallback()) if (!_function.isConstructor())
{
solAssert(m_context.numberOfLocalVariables() == 0, "");
if (!_function.isFallback())
m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction);
}
return false; return false;
} }
@ -999,10 +1003,10 @@ eth::AssemblyPointer ContractCompiler::cloneRuntime() const
void ContractCompiler::popScopedVariables(ASTNode const* _node) void ContractCompiler::popScopedVariables(ASTNode const* _node)
{ {
unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node); unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node);
m_context.removeVariablesAboveStackHeight(blockHeight);
solAssert(m_context.stackHeight() >= blockHeight, ""); solAssert(m_context.stackHeight() >= blockHeight, "");
unsigned stackDiff = m_context.stackHeight() - blockHeight; unsigned stackDiff = m_context.stackHeight() - blockHeight;
CompilerUtils(m_context).popStackSlots(stackDiff); CompilerUtils(m_context).popStackSlots(stackDiff);
m_context.removeVariablesAboveStackHeight(blockHeight);
m_scopeStackHeight[m_modifierDepth].erase(_node); m_scopeStackHeight[m_modifierDepth].erase(_node);
if (m_scopeStackHeight[m_modifierDepth].size() == 0) if (m_scopeStackHeight[m_modifierDepth].size() == 0)
m_scopeStackHeight.erase(m_modifierDepth); m_scopeStackHeight.erase(m_modifierDepth);

View File

@ -9494,7 +9494,9 @@ BOOST_AUTO_TEST_CASE(break_in_modifier)
} }
} }
function f() run { function f() run {
x++; uint k = x;
uint t = k + 1;
x = t;
} }
} }
)"; )";
@ -9516,7 +9518,9 @@ BOOST_AUTO_TEST_CASE(continue_in_modifier)
} }
} }
function f() run { function f() run {
x++; uint k = x;
uint t = k + 1;
x = t;
} }
} }
)"; )";
@ -9538,7 +9542,9 @@ BOOST_AUTO_TEST_CASE(return_in_modifier)
} }
} }
function f() run { function f() run {
x++; uint k = x;
uint t = k + 1;
x = t;
} }
} }
)"; )";
@ -9560,7 +9566,9 @@ BOOST_AUTO_TEST_CASE(stacked_return_with_modifiers)
} }
} }
function f() run { function f() run {
x++; uint k = x;
uint t = k + 1;
x = t;
} }
} }
)"; )";