diff options
Diffstat (limited to 'libsolidity/analysis/StaticAnalyzer.cpp')
-rw-r--r-- | libsolidity/analysis/StaticAnalyzer.cpp | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 369376fa..b1b31163 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -21,18 +21,18 @@ */ #include <libsolidity/analysis/StaticAnalyzer.h> -#include <memory> #include <libsolidity/ast/AST.h> +#include <libsolidity/interface/ErrorReporter.h> +#include <memory> using namespace std; using namespace dev; using namespace dev::solidity; - bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit) { _sourceUnit.accept(*this); - return Error::containsOnlyWarnings(m_errors); + return Error::containsOnlyWarnings(m_errorReporter.errors()); } bool StaticAnalyzer::visit(ContractDefinition const& _contract) @@ -63,7 +63,7 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&) m_nonPayablePublic = false; for (auto const& var: m_localVarUseCount) if (var.second == 0) - warning(var.first->location(), "Unused local variable"); + m_errorReporter.warning(var.first->location(), "Unused local variable"); m_localVarUseCount.clear(); } @@ -105,7 +105,11 @@ bool StaticAnalyzer::visit(Return const& _return) bool StaticAnalyzer::visit(ExpressionStatement const& _statement) { if (_statement.expression().annotation().isPure) - warning(_statement.location(), "Statement has no effect."); + m_errorReporter.warning( + _statement.location(), + "Statement has no effect." + ); + return true; } @@ -114,17 +118,36 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) if (m_nonPayablePublic && !m_library) if (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type.get())) if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "value") - warning(_memberAccess.location(), "\"msg.value\" used in non-payable function. Do you want to add the \"payable\" modifier to this function?"); + m_errorReporter.warning( + _memberAccess.location(), + "\"msg.value\" used in non-payable function. Do you want to add the \"payable\" modifier to this function?" + ); + + if (_memberAccess.memberName() == "callcode") + if (auto const* type = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type.get())) + if (type->kind() == FunctionType::Kind::BareCallCode) + m_errorReporter.warning( + _memberAccess.location(), + "\"callcode\" has been deprecated in favour of \"delegatecall\"." + ); return true; } -void StaticAnalyzer::warning(SourceLocation const& _location, string const& _description) +bool StaticAnalyzer::visit(InlineAssembly const& _inlineAssembly) { - auto err = make_shared<Error>(Error::Type::Warning); - *err << - errinfo_sourceLocation(_location) << - errinfo_comment(_description); + if (!m_currentFunction) + return true; - m_errors.push_back(err); + for (auto const& ref: _inlineAssembly.annotation().externalReferences) + { + if (auto var = dynamic_cast<VariableDeclaration const*>(ref.second.declaration)) + { + solAssert(!var->name().empty(), ""); + if (var->isLocalVariable()) + m_localVarUseCount[var] += 1; + } + } + + return true; } |