Warn if this is used in constructor

This commit is contained in:
Alex Beregszaszi 2017-02-02 11:03:37 +00:00 committed by Rhett Aultman
parent 84f8e7a467
commit b3db1c361c
2 changed files with 15 additions and 0 deletions

View File

@ -38,12 +38,14 @@ bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit)
bool StaticAnalyzer::visit(ContractDefinition const& _contract) bool StaticAnalyzer::visit(ContractDefinition const& _contract)
{ {
m_library = _contract.isLibrary(); m_library = _contract.isLibrary();
m_currentContract = &_contract;
return true; return true;
} }
void StaticAnalyzer::endVisit(ContractDefinition const&) void StaticAnalyzer::endVisit(ContractDefinition const&)
{ {
m_library = false; m_library = false;
m_currentContract = nullptr;
} }
bool StaticAnalyzer::visit(FunctionDefinition const& _function) bool StaticAnalyzer::visit(FunctionDefinition const& _function)
@ -54,6 +56,7 @@ bool StaticAnalyzer::visit(FunctionDefinition const& _function)
solAssert(!m_currentFunction, ""); solAssert(!m_currentFunction, "");
solAssert(m_localVarUseCount.empty(), ""); solAssert(m_localVarUseCount.empty(), "");
m_nonPayablePublic = _function.isPublic() && !_function.isPayable(); m_nonPayablePublic = _function.isPublic() && !_function.isPayable();
m_constructor = _function.isConstructor();
return true; return true;
} }
@ -61,6 +64,7 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&)
{ {
m_currentFunction = nullptr; m_currentFunction = nullptr;
m_nonPayablePublic = false; m_nonPayablePublic = false;
m_constructor = false;
for (auto const& var: m_localVarUseCount) for (auto const& var: m_localVarUseCount)
if (var.second == 0) if (var.second == 0)
m_errorReporter.warning(var.first->location(), "Unused local variable"); m_errorReporter.warning(var.first->location(), "Unused local variable");
@ -131,6 +135,11 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess)
"\"callcode\" has been deprecated in favour of \"delegatecall\"." "\"callcode\" has been deprecated in favour of \"delegatecall\"."
); );
if (m_constructor && m_currentContract)
if (ContractType const* type = dynamic_cast<ContractType const*>(_memberAccess.expression().annotation().type.get()))
if (type->contractDefinition() == *m_currentContract)
warning(_memberAccess.location(), "\"this\" used in constructor.");
return true; return true;
} }

View File

@ -77,6 +77,12 @@ private:
std::map<VariableDeclaration const*, int> m_localVarUseCount; std::map<VariableDeclaration const*, int> m_localVarUseCount;
FunctionDefinition const* m_currentFunction = nullptr; FunctionDefinition const* m_currentFunction = nullptr;
/// Flag that indicates a constructor.
bool m_constructor = false;
/// Current contract.
ContractDefinition const* m_currentContract = nullptr;
}; };
} }