diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 22 | ||||
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.h | 3 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 2 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 20 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.h | 1 |
5 files changed, 47 insertions, 1 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 2742dcf2..aac90311 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -26,6 +26,8 @@ #include <libsolidity/analysis/TypeChecker.h> #include <libsolidity/interface/ErrorReporter.h> +#include <boost/algorithm/string.hpp> + using namespace std; namespace dev @@ -232,6 +234,26 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations( return uniqueFunctions; } +void NameAndTypeResolver::warnVariablesNamedLikeInstructions() +{ + for (auto const& instruction: c_instructions) + { + string const instructionName{boost::algorithm::to_lower_copy(instruction.first)}; + auto declarations = nameFromCurrentScope(instructionName); + for (Declaration const* const declaration: declarations) + { + solAssert(!!declaration, ""); + if (dynamic_cast<MagicVariableDeclaration const* const>(declaration)) + // Don't warn the user for what the user did not. + continue; + m_errorReporter.warning( + declaration->location(), + "Variable is shadowed in inline assembly by an instruction of the same name" + ); + } + } +} + bool NameAndTypeResolver::resolveNamesAndTypesInternal(ASTNode& _node, bool _resolveInsideCode) { if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(&_node)) diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h index 0441867d..84628778 100644 --- a/libsolidity/analysis/NameAndTypeResolver.h +++ b/libsolidity/analysis/NameAndTypeResolver.h @@ -90,6 +90,9 @@ public: std::vector<Declaration const*> const& _declarations ); + /// Generate and store warnings about variables that are named like instructions. + void warnVariablesNamedLikeInstructions(); + private: /// Internal version of @a resolveNamesAndTypes (called from there) throws exceptions on fatal errors. bool resolveNamesAndTypesInternal(ASTNode& _node, bool _resolveInsideCode = true); diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index edf2fc02..2a5f27df 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -162,6 +162,8 @@ void ReferencesResolver::endVisit(ArrayTypeName const& _typeName) bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly) { + m_resolver.warnVariablesNamedLikeInstructions(); + // Errors created in this stage are completely ignored because we do not yet know // the type and size of external identifiers, which would result in false errors. // The only purpose of this step is to fill the inline assembly annotation with diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 13852880..36ac0e75 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -65,6 +65,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; } @@ -149,6 +150,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; } @@ -431,7 +433,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 +444,20 @@ 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) +{ + switch (_instr) + { + case solidity::Instruction::RETURNDATASIZE: + case solidity::Instruction::RETURNDATACOPY: + m_errorReporter.warning( + _location, + "The RETURNDATASIZE/RETURNDATACOPY instructions are only available after " + "the Metropolis hard fork. Before that they act as an invalid instruction." + ); + break; + default: + break; + } +} diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index e7748bcf..55b409ba 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -97,6 +97,7 @@ private: Scope& scope(assembly::Block const* _block); void expectValidType(std::string const& type, SourceLocation const& _location); + void warnOnFutureInstruction(solidity::Instruction _instr, SourceLocation const& _location); int m_stackHeight = 0; julia::ExternalIdentifierAccess::Resolver m_resolver; |