diff options
-rw-r--r-- | libsolidity/analysis/StaticAnalyzer.cpp | 17 | ||||
-rw-r--r-- | libsolidity/analysis/StaticAnalyzer.h | 1 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 12 |
3 files changed, 17 insertions, 13 deletions
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 26e77283..369376fa 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -50,7 +50,9 @@ bool StaticAnalyzer::visit(FunctionDefinition const& _function) { if (_function.isImplemented()) m_currentFunction = &_function; - m_localVarUseCount.clear(); + else + solAssert(!m_currentFunction, ""); + solAssert(m_localVarUseCount.empty(), ""); m_nonPayablePublic = _function.isPublic() && !_function.isPayable(); return true; } @@ -62,19 +64,18 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&) for (auto const& var: m_localVarUseCount) if (var.second == 0) warning(var.first->location(), "Unused local variable"); + m_localVarUseCount.clear(); } bool StaticAnalyzer::visit(Identifier const& _identifier) { if (m_currentFunction) - { if (auto var = dynamic_cast<VariableDeclaration const*>(_identifier.annotation().referencedDeclaration)) { solAssert(!var->name().empty(), ""); if (var->isLocalVariable()) m_localVarUseCount[var] += 1; } - } return true; } @@ -84,14 +85,8 @@ bool StaticAnalyzer::visit(VariableDeclaration const& _variable) { solAssert(_variable.isLocalVariable(), ""); if (_variable.name() != "") - { - // The variable may have been used before reaching the - // declaration. If it was, we must not reset the counter, - // but since [] will insert the default 0, we really just - // need to access the map here and let it do the rest on its - // own. - m_localVarUseCount[&_variable]; - } + // This is not a no-op, the entry might pre-exist. + m_localVarUseCount[&_variable] += 0; } return true; } diff --git a/libsolidity/analysis/StaticAnalyzer.h b/libsolidity/analysis/StaticAnalyzer.h index cf2e2175..ab72e7d9 100644 --- a/libsolidity/analysis/StaticAnalyzer.h +++ b/libsolidity/analysis/StaticAnalyzer.h @@ -74,6 +74,7 @@ private: /// Flag that indicates whether a public function does not contain the "payable" modifier. bool m_nonPayablePublic = false; + /// Number of uses of each (named) local variable in a function, counter is initialized with zero. std::map<VariableDeclaration const*, int> m_localVarUseCount; FunctionDefinition const* m_currentFunction = nullptr; diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index ace8ef46..fd50609d 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -5658,6 +5658,14 @@ BOOST_AUTO_TEST_CASE(warn_unused_return_param) CHECK_WARNING(text, "Unused"); text = R"( contract C { + function f() returns (uint a) { + return; + } + } + )"; + CHECK_WARNING(text, "Unused"); + text = R"( + contract C { function f() returns (uint) { } } @@ -5699,8 +5707,8 @@ BOOST_AUTO_TEST_CASE(no_unused_dec_after_use) char const* text = R"( contract C { function f() { - a = 7; - uint a; + a = 7; + uint a; } } )"; |