From 31e727c4dc1937334b787175bcb283afe1575590 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 24 May 2017 21:51:54 +0100 Subject: [PATCH] Warn if returndatasize/returndatacopy is used --- libsolidity/inlineasm/AsmAnalysis.cpp | 20 ++++++++++++++++++++ libsolidity/inlineasm/AsmAnalysis.h | 1 + 2 files changed, 21 insertions(+) diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 65b935f23b32..cd3c0f2dd967 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -66,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; } @@ -157,6 +158,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; } @@ -411,3 +413,21 @@ Scope& AsmAnalyzer::scope(Block const* _block) solAssert(scopePtr, "Scope requested but not present."); return *scopePtr; } + +void AsmAnalyzer::warnOnFutureInstruction(solidity::Instruction _instr, SourceLocation const& _location) +{ + switch (_instr) + { + case solidity::Instruction::RETURNDATASIZE: + case solidity::Instruction::RETURNDATACOPY: + m_errors.push_back(make_shared( + Error::Type::Warning, + "The RETURNDATASIZE/RETURNDATACOPY instructions are only available after " + "the Metropolis hard fork. Before that they act as an invalid instruction.", + _location + )); + break; + default: + break; + } +} diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index f09e4b592cd9..619c9f154be8 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -86,6 +86,7 @@ class AsmAnalyzer: public boost::static_visitor bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1)); bool expectDeposit(int _deposit, int _oldHeight, SourceLocation const& _location); Scope& scope(assembly::Block const* _block); + void warnOnFutureInstruction(solidity::Instruction _instr, SourceLocation const& _location); /// This is used when we enter the body of a function definition. There, the parameters /// and return parameters appear as variables which are already on the stack before