diff options
Diffstat (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp')
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 13852880..1a529118 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -29,6 +29,7 @@ #include <libsolidity/interface/Utils.h> #include <boost/range/adaptor/reversed.hpp> +#include <boost/algorithm/string.hpp> #include <memory> #include <functional> @@ -65,6 +66,7 @@ bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) auto const& info = instructionInfo(_instruction.instruction); m_stackHeight += info.ret - info.args; m_info.stackHeightInfo[&_instruction] = m_stackHeight; + warnOnFutureInstruction(_instruction.instruction, _instruction.location); return true; } @@ -91,7 +93,7 @@ bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier) if (m_currentScope->lookup(_identifier.name, Scope::Visitor( [&](Scope::Variable const& _var) { - if (!_var.active) + if (!m_activeVariables.count(&_var)) { m_errorReporter.declarationError( _identifier.location, @@ -149,6 +151,7 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) if (!(*this)(_instr.instruction)) success = false; m_info.stackHeightInfo[&_instr] = m_stackHeight; + warnOnFutureInstruction(_instr.instruction.instruction, _instr.location); return success; } @@ -185,7 +188,7 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl) for (auto const& variable: _varDecl.variables) { expectValidType(variable.type, variable.location); - boost::get<Scope::Variable>(m_currentScope->identifiers.at(variable.name)).active = true; + m_activeVariables.insert(&boost::get<Scope::Variable>(m_currentScope->identifiers.at(variable.name))); } m_info.stackHeightInfo[&_varDecl] = m_stackHeight; return success; @@ -199,7 +202,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef) for (auto const& var: _funDef.arguments + _funDef.returns) { expectValidType(var.type, var.location); - boost::get<Scope::Variable>(varScope.identifiers.at(var.name)).active = true; + m_activeVariables.insert(&boost::get<Scope::Variable>(varScope.identifiers.at(var.name))); } int const stackHeight = m_stackHeight; @@ -382,7 +385,7 @@ bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t m_errorReporter.typeError(_variable.location, "Assignment requires variable."); success = false; } - else if (!boost::get<Scope::Variable>(*var).active) + else if (!m_activeVariables.count(&boost::get<Scope::Variable>(*var))) { m_errorReporter.declarationError( _variable.location, @@ -431,7 +434,6 @@ Scope& AsmAnalyzer::scope(Block const* _block) solAssert(scopePtr, "Scope requested but not present."); return *scopePtr; } - void AsmAnalyzer::expectValidType(string const& type, SourceLocation const& _location) { if (!m_julia) @@ -443,3 +445,21 @@ void AsmAnalyzer::expectValidType(string const& type, SourceLocation const& _loc "\"" + type + "\" is not a valid type (user defined types are not yet supported)." ); } + +void AsmAnalyzer::warnOnFutureInstruction(solidity::Instruction _instr, SourceLocation const& _location) +{ + static set<solidity::Instruction> futureInstructions{ + solidity::Instruction::CREATE2, + solidity::Instruction::RETURNDATACOPY, + solidity::Instruction::RETURNDATASIZE, + solidity::Instruction::STATICCALL + }; + if (futureInstructions.count(_instr)) + m_errorReporter.warning( + _location, + "The \"" + + boost::to_lower_copy(instructionInfo(_instr).name) + + "\" instruction is only available after " + + "the Metropolis hard fork. Before that it acts as an invalid instruction." + ); +} |