aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.cpp22
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.h3
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp2
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp20
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.h1
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;