From ae02bb5aadfa49636f9931524dbc026c855201f1 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 4 Jan 2018 23:25:41 +0000 Subject: Raise error on oversized number literals in assembly --- libsolidity/inlineasm/AsmAnalysis.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 2d6e58de..e672d5ef 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -82,6 +82,14 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal) ); return false; } + else if (_literal.kind == assembly::LiteralKind::Number && bigint(_literal.value) > u256(-1)) + { + m_errorReporter.typeError( + _literal.location, + "Number literal too large (> 256 bits)" + ); + return false; + } m_info.stackHeightInfo[&_literal] = m_stackHeight; return true; } -- cgit v1.2.3 From 42856e0f53c1cb9be61e9f24b9f09a7b0179cd55 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 22 Feb 2018 01:00:26 +0100 Subject: Add assertion for boolean literals in Julia-mode --- libsolidity/inlineasm/AsmAnalysis.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index e672d5ef..a05ac57d 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -90,6 +90,11 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal) ); return false; } + else if (_literal.kind == assembly::LiteralKind::Boolean) + { + solAssert(m_flavour == AsmFlavour::IULIA, ""); + solAssert(_literal.value == "true" || _literal.value == "false", ""); + } m_info.stackHeightInfo[&_literal] = m_stackHeight; return true; } -- cgit v1.2.3 From 468d0f6199e71f0c7f4b8bd667c8f31feba41a9d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 15 Jun 2017 12:14:14 +0100 Subject: Warn on using shift instructions --- libsolidity/inlineasm/AsmAnalysis.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index a05ac57d..7653ee51 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -548,6 +548,22 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio "the Metropolis hard fork. Before that it acts as an invalid instruction." ); + static set experimentalInstructions{ + solidity::Instruction::SHL, + solidity::Instruction::SHR, + solidity::Instruction::SAR, + solidity::Instruction::ROL, + solidity::Instruction::ROR + }; + if (experimentalInstructions.count(_instr)) + m_errorReporter.warning( + _location, + "The \"" + + boost::to_lower_copy(instructionInfo(_instr).name) + + "\" instruction is only available after " + + "the Constantinople hard fork. Before that it acts as an invalid instruction." + ); + if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST) m_errorReporter.warning( _location, -- cgit v1.2.3 From afa4a48e3770630a744ef98ccd518601e1f35c86 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 9 Jul 2017 08:42:54 +0100 Subject: Remove ROL/ROR as they are not part of EIP145 anymore --- libsolidity/inlineasm/AsmAnalysis.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 7653ee51..1030523a 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -551,9 +551,7 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio static set experimentalInstructions{ solidity::Instruction::SHL, solidity::Instruction::SHR, - solidity::Instruction::SAR, - solidity::Instruction::ROL, - solidity::Instruction::ROR + solidity::Instruction::SAR }; if (experimentalInstructions.count(_instr)) m_errorReporter.warning( -- cgit v1.2.3 From dc317a44e031d45ebf745b47248bf06bc92d58bf Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 23 Feb 2018 11:42:53 +0100 Subject: Provide EVM version to assembly analysis. --- libsolidity/inlineasm/AsmAnalysis.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 1030523a..efa0410d 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -533,19 +533,33 @@ void AsmAnalyzer::expectValidType(string const& type, SourceLocation const& _loc void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocation const& _location) { - static set futureInstructions{ - solidity::Instruction::CREATE2, - solidity::Instruction::RETURNDATACOPY, - solidity::Instruction::RETURNDATASIZE, - solidity::Instruction::STATICCALL - }; - if (futureInstructions.count(_instr)) + // We assume that returndatacopy, returndatasize and staticcall are either all available + // or all not available. + solAssert(m_evmVersion.supportsReturndata() == m_evmVersion.hasStaticCall(), ""); + + if (_instr == solidity::Instruction::CREATE2) 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." + + "\" instruction is not supported by the VM version \"" + + "" + m_evmVersion.name() + + "\" you are currently compiling for. " + + "It will be interpreted as an invalid instruction on this VM." + ); + else if (( + _instr == solidity::Instruction::RETURNDATACOPY || + _instr == solidity::Instruction::RETURNDATASIZE || + _instr == solidity::Instruction::STATICCALL + ) && !m_evmVersion.supportsReturndata()) + m_errorReporter.warning( + _location, + "The \"" + + boost::to_lower_copy(instructionInfo(_instr).name) + + "\" instruction is only available for Byzantium-compatible VMs. " + + "You are currently compiling for \"" + + m_evmVersion.name() + + "\", where it will be interpreted as an invalid instruction." ); static set experimentalInstructions{ -- cgit v1.2.3 From 5a54cd5c708227ad6982b06de7b799ece5065917 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 28 Feb 2018 08:43:18 +0100 Subject: Only warn for shift instructions if not using constantinople --- libsolidity/inlineasm/AsmAnalysis.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index efa0410d..a7f764a5 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -561,19 +561,19 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio m_evmVersion.name() + "\", where it will be interpreted as an invalid instruction." ); - - static set experimentalInstructions{ - solidity::Instruction::SHL, - solidity::Instruction::SHR, - solidity::Instruction::SAR - }; - if (experimentalInstructions.count(_instr)) + else if (( + _instr == solidity::Instruction::SHL || + _instr == solidity::Instruction::SHR || + _instr == solidity::Instruction::SAR + ) && !m_evmVersion.hasBitwiseShifting()) m_errorReporter.warning( _location, "The \"" + boost::to_lower_copy(instructionInfo(_instr).name) - + "\" instruction is only available after " + - "the Constantinople hard fork. Before that it acts as an invalid instruction." + + "\" instruction is only available for Constantinople-compatible VMs. " + + "You are currently compiling for \"" + + m_evmVersion.name() + + "\", where it will be interpreted as an invalid instruction." ); if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST) -- cgit v1.2.3 From fd1662d1c49776232b491f1871391ad1cd90309a Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 15 Feb 2018 15:18:09 +0100 Subject: Warn about using loose inline assembly features as experimental 0.5.0 feature. --- libsolidity/inlineasm/AsmAnalysis.cpp | 45 +++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) (limited to 'libsolidity/inlineasm/AsmAnalysis.cpp') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index a7f764a5..abf7ddf2 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -54,7 +54,10 @@ bool AsmAnalyzer::analyze(Block const& _block) bool AsmAnalyzer::operator()(Label const& _label) { - solAssert(m_flavour == AsmFlavour::Loose, ""); + checkLooseFeature( + _label.location, + "The use of labels is deprecated. Please use \"if\", \"switch\", \"for\" or function calls instead." + ); m_info.stackHeightInfo[&_label] = m_stackHeight; warnOnInstructions(solidity::Instruction::JUMPDEST, _label.location); return true; @@ -62,7 +65,10 @@ bool AsmAnalyzer::operator()(Label const& _label) bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) { - solAssert(m_flavour == AsmFlavour::Loose, ""); + checkLooseFeature( + _instruction.location, + "The use of non-functional instructions is deprecated. Please use functional notation instead." + ); auto const& info = instructionInfo(_instruction.instruction); m_stackHeight += info.ret - info.args; m_info.stackHeightInfo[&_instruction] = m_stackHeight; @@ -170,18 +176,31 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) bool AsmAnalyzer::operator()(assembly::ExpressionStatement const& _statement) { - size_t initialStackHeight = m_stackHeight; + int initialStackHeight = m_stackHeight; bool success = boost::apply_visitor(*this, _statement.expression); - if (m_flavour != AsmFlavour::Loose) - if (!expectDeposit(0, initialStackHeight, _statement.location)) + if (m_stackHeight != initialStackHeight && (m_flavour != AsmFlavour::Loose || m_errorTypeForLoose)) + { + Error::Type errorType = m_flavour == AsmFlavour::Loose ? *m_errorTypeForLoose : Error::Type::TypeError; + string msg = + "Top-level expressions are not supposed to return values (this expression returns " + + boost::lexical_cast(m_stackHeight - initialStackHeight) + + " value" + + (m_stackHeight - initialStackHeight == 1 ? "" : "s") + + "). Use ``pop()`` or assign them."; + m_errorReporter.error(errorType, _statement.location, msg); + if (errorType != Error::Type::Warning) success = false; + } m_info.stackHeightInfo[&_statement] = m_stackHeight; return success; } bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment) { - solAssert(m_flavour == AsmFlavour::Loose, ""); + checkLooseFeature( + _assignment.location, + "The use of stack assignment is deprecated. Please use assignment in functional notation instead." + ); bool success = checkAssignment(_assignment.variableName, size_t(-1)); m_info.stackHeightInfo[&_assignment] = m_stackHeight; return success; @@ -577,10 +596,22 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio ); if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST) - m_errorReporter.warning( + { + solAssert(m_flavour == AsmFlavour::Loose, ""); + m_errorReporter.error( + m_errorTypeForLoose ? *m_errorTypeForLoose : Error::Type::Warning, _location, "Jump instructions and labels are low-level EVM features that can lead to " "incorrect stack access. Because of that they are discouraged. " "Please consider using \"switch\", \"if\" or \"for\" statements instead." ); + } +} + +void AsmAnalyzer::checkLooseFeature(SourceLocation const& _location, string const& _description) +{ + if (m_flavour != AsmFlavour::Loose) + solAssert(false, _description); + else if (m_errorTypeForLoose) + m_errorReporter.error(*m_errorTypeForLoose, _location, _description); } -- cgit v1.2.3