aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r--libsolidity/analysis/PostTypeChecker.cpp3
-rw-r--r--libsolidity/analysis/StaticAnalyzer.cpp45
-rw-r--r--libsolidity/analysis/StaticAnalyzer.h9
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp17
-rw-r--r--libsolidity/analysis/SyntaxChecker.h4
5 files changed, 77 insertions, 1 deletions
diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp
index cae77c74..e8da3ca4 100644
--- a/libsolidity/analysis/PostTypeChecker.cpp
+++ b/libsolidity/analysis/PostTypeChecker.cpp
@@ -58,6 +58,9 @@ void PostTypeChecker::endVisit(ContractDefinition const&)
for (auto declaration: m_constVariables)
if (auto identifier = findCycle(declaration))
typeError(declaration->location(), "The value of the constant " + declaration->name() + " has a cyclic dependency via " + identifier->name() + ".");
+
+ m_constVariables.clear();
+ m_constVariableDependencies.clear();
}
bool PostTypeChecker::visit(VariableDeclaration const& _variable)
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp
index 190d2420..369376fa 100644
--- a/libsolidity/analysis/StaticAnalyzer.cpp
+++ b/libsolidity/analysis/StaticAnalyzer.cpp
@@ -48,13 +48,58 @@ void StaticAnalyzer::endVisit(ContractDefinition const&)
bool StaticAnalyzer::visit(FunctionDefinition const& _function)
{
+ if (_function.isImplemented())
+ m_currentFunction = &_function;
+ else
+ solAssert(!m_currentFunction, "");
+ solAssert(m_localVarUseCount.empty(), "");
m_nonPayablePublic = _function.isPublic() && !_function.isPayable();
return true;
}
void StaticAnalyzer::endVisit(FunctionDefinition const&)
{
+ m_currentFunction = nullptr;
m_nonPayablePublic = false;
+ 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;
+}
+
+bool StaticAnalyzer::visit(VariableDeclaration const& _variable)
+{
+ if (m_currentFunction)
+ {
+ solAssert(_variable.isLocalVariable(), "");
+ if (_variable.name() != "")
+ // This is not a no-op, the entry might pre-exist.
+ m_localVarUseCount[&_variable] += 0;
+ }
+ return true;
+}
+
+bool StaticAnalyzer::visit(Return const& _return)
+{
+ // If the return has an expression, it counts as
+ // a "use" of the return parameters.
+ if (m_currentFunction && _return.expression())
+ for (auto const& var: m_currentFunction->returnParameters())
+ if (!var->name().empty())
+ m_localVarUseCount[var.get()] += 1;
+ return true;
}
bool StaticAnalyzer::visit(ExpressionStatement const& _statement)
diff --git a/libsolidity/analysis/StaticAnalyzer.h b/libsolidity/analysis/StaticAnalyzer.h
index 84342322..ab72e7d9 100644
--- a/libsolidity/analysis/StaticAnalyzer.h
+++ b/libsolidity/analysis/StaticAnalyzer.h
@@ -61,7 +61,9 @@ private:
virtual void endVisit(FunctionDefinition const& _function) override;
virtual bool visit(ExpressionStatement const& _statement) override;
-
+ virtual bool visit(VariableDeclaration const& _variable) override;
+ virtual bool visit(Identifier const& _identifier) override;
+ virtual bool visit(Return const& _return) override;
virtual bool visit(MemberAccess const& _memberAccess) override;
ErrorList& m_errors;
@@ -71,6 +73,11 @@ 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/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index 89014133..94e82a87 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -32,6 +32,16 @@ bool SyntaxChecker::checkSyntax(ASTNode const& _astRoot)
return Error::containsOnlyWarnings(m_errors);
}
+void SyntaxChecker::warning(SourceLocation const& _location, string const& _description)
+{
+ auto err = make_shared<Error>(Error::Type::Warning);
+ *err <<
+ errinfo_sourceLocation(_location) <<
+ errinfo_comment(_description);
+
+ m_errors.push_back(err);
+}
+
void SyntaxChecker::syntaxError(SourceLocation const& _location, std::string const& _description)
{
auto err = make_shared<Error>(Error::Type::SyntaxError);
@@ -148,6 +158,13 @@ bool SyntaxChecker::visit(Break const& _breakStatement)
return true;
}
+bool SyntaxChecker::visit(UnaryOperation const& _operation)
+{
+ if (_operation.getOperator() == Token::Add)
+ warning(_operation.location(), "Use of unary + is deprecated.");
+ return true;
+}
+
bool SyntaxChecker::visit(PlaceholderStatement const&)
{
m_placeholderFound = true;
diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h
index 308e128b..8d7dcdd3 100644
--- a/libsolidity/analysis/SyntaxChecker.h
+++ b/libsolidity/analysis/SyntaxChecker.h
@@ -32,6 +32,7 @@ namespace solidity
* The module that performs syntax analysis on the AST:
* - whether continue/break is in a for/while loop.
* - whether a modifier contains at least one '_'
+ * - issues deprecation warnings for unary '+'
*/
class SyntaxChecker: private ASTConstVisitor
{
@@ -43,6 +44,7 @@ public:
private:
/// Adds a new error to the list of errors.
+ void warning(SourceLocation const& _location, std::string const& _description);
void syntaxError(SourceLocation const& _location, std::string const& _description);
virtual bool visit(SourceUnit const& _sourceUnit) override;
@@ -60,6 +62,8 @@ private:
virtual bool visit(Continue const& _continueStatement) override;
virtual bool visit(Break const& _breakStatement) override;
+ virtual bool visit(UnaryOperation const& _operation) override;
+
virtual bool visit(PlaceholderStatement const& _placeholderStatement) override;
ErrorList& m_errors;