From 2c56e530467c088c5096d95422313ca211786eca Mon Sep 17 00:00:00 2001 From: bitshift Date: Wed, 7 Mar 2018 10:48:10 +0100 Subject: Changes deprecation and adjusts tests. --- libsolidity/analysis/StaticAnalyzer.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'libsolidity/analysis/StaticAnalyzer.cpp') diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index d4de219a..6aee260e 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -142,6 +142,7 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) bool const v050 = m_currentContract->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); if (MagicType const* type = dynamic_cast(_memberAccess.expression().annotation().type.get())) + { if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "gas") { if (v050) @@ -155,6 +156,20 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) "\"msg.gas\" has been deprecated in favor of \"gasleft()\"" ); } + if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash") + { + if (v050) + m_errorReporter.typeError( + _memberAccess.location(), + "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" + ); + else + m_errorReporter.warning( + _memberAccess.location(), + "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" + ); + } + } if (m_nonPayablePublic && !m_library) if (MagicType const* type = dynamic_cast(_memberAccess.expression().annotation().type.get())) -- cgit v1.2.3 From 8fe1cfb12ef49a74eaebed56d160e88cfd9a4de2 Mon Sep 17 00:00:00 2001 From: bitshift Date: Fri, 9 Mar 2018 17:38:17 +0100 Subject: Defaults to external visibility for interfaces. --- libsolidity/analysis/StaticAnalyzer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libsolidity/analysis/StaticAnalyzer.cpp') diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 6aee260e..20464765 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -50,6 +50,14 @@ void StaticAnalyzer::endVisit(ContractDefinition const&) bool StaticAnalyzer::visit(FunctionDefinition const& _function) { + const bool isInterface = m_currentContract->contractKind() == ContractDefinition::ContractKind::Interface; + if (_function.noVisibilitySpecified()) + m_errorReporter.warning( + _function.location(), + "No visibility specified. Defaulting to \"" + + (isInterface ? "external" : Declaration::visibilityToString(_function.visibility())) + + "\"." + ); if (_function.isImplemented()) m_currentFunction = &_function; else -- cgit v1.2.3 From f9efa417492916546d23115da7a55e86090d47dd Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 28 Mar 2018 18:10:32 +0200 Subject: Makes visibility warning more concise. --- libsolidity/analysis/StaticAnalyzer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'libsolidity/analysis/StaticAnalyzer.cpp') diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 20464765..d96f8748 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -51,12 +51,14 @@ void StaticAnalyzer::endVisit(ContractDefinition const&) bool StaticAnalyzer::visit(FunctionDefinition const& _function) { const bool isInterface = m_currentContract->contractKind() == ContractDefinition::ContractKind::Interface; + if (_function.noVisibilitySpecified()) m_errorReporter.warning( _function.location(), "No visibility specified. Defaulting to \"" + - (isInterface ? "external" : Declaration::visibilityToString(_function.visibility())) + - "\"." + Declaration::visibilityToString(_function.visibility()) + + "\". " + + (isInterface ? "In interfaces it defaults to external." : "") ); if (_function.isImplemented()) m_currentFunction = &_function; -- cgit v1.2.3 From b2753aa05307d8142a319212c5fdd9a3c7f383fe Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Apr 2018 18:10:26 +0200 Subject: Static Analyzer: Fix non-deterministic order of unused variable warnings. --- libsolidity/analysis/StaticAnalyzer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'libsolidity/analysis/StaticAnalyzer.cpp') diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index d96f8748..33b0e296 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -78,13 +78,13 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&) for (auto const& var: m_localVarUseCount) if (var.second == 0) { - if (var.first->isCallableParameter()) + if (var.first.second->isCallableParameter()) m_errorReporter.warning( - var.first->location(), + var.first.second->location(), "Unused function parameter. Remove or comment out the variable name to silence this warning." ); else - m_errorReporter.warning(var.first->location(), "Unused local variable."); + m_errorReporter.warning(var.first.second->location(), "Unused local variable."); } m_localVarUseCount.clear(); @@ -97,7 +97,7 @@ bool StaticAnalyzer::visit(Identifier const& _identifier) { solAssert(!var->name().empty(), ""); if (var->isLocalVariable()) - m_localVarUseCount[var] += 1; + m_localVarUseCount[make_pair(var->id(), var)] += 1; } return true; } @@ -109,7 +109,7 @@ bool StaticAnalyzer::visit(VariableDeclaration const& _variable) solAssert(_variable.isLocalVariable(), ""); if (_variable.name() != "") // This is not a no-op, the entry might pre-exist. - m_localVarUseCount[&_variable] += 0; + m_localVarUseCount[make_pair(_variable.id(), &_variable)] += 0; } else if (_variable.isStateVariable()) { @@ -132,7 +132,7 @@ bool StaticAnalyzer::visit(Return const& _return) if (m_currentFunction && _return.expression()) for (auto const& var: m_currentFunction->returnParameters()) if (!var->name().empty()) - m_localVarUseCount[var.get()] += 1; + m_localVarUseCount[make_pair(var->id(), var.get())] += 1; return true; } @@ -224,7 +224,7 @@ bool StaticAnalyzer::visit(InlineAssembly const& _inlineAssembly) { solAssert(!var->name().empty(), ""); if (var->isLocalVariable()) - m_localVarUseCount[var] += 1; + m_localVarUseCount[make_pair(var->id(), var)] += 1; } } -- cgit v1.2.3 From daa69df447e167fe75d57a5bbbabee4d637218a4 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 9 Apr 2018 15:22:45 +0200 Subject: Error on invalid arithmetic with constant expressions. --- libsolidity/analysis/StaticAnalyzer.cpp | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'libsolidity/analysis/StaticAnalyzer.cpp') diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 33b0e296..51aa0b28 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -231,6 +232,47 @@ bool StaticAnalyzer::visit(InlineAssembly const& _inlineAssembly) return true; } +bool StaticAnalyzer::visit(BinaryOperation const& _operation) +{ + if ( + _operation.rightExpression().annotation().isPure && + (_operation.getOperator() == Token::Div || _operation.getOperator() == Token::Mod) + ) + if (auto rhs = dynamic_pointer_cast( + ConstantEvaluator(m_errorReporter).evaluate(_operation.rightExpression()) + )) + if (rhs->isZero()) + m_errorReporter.typeError( + _operation.location(), + (_operation.getOperator() == Token::Div) ? "Division by zero." : "Modulo zero." + ); + + return true; +} + +bool StaticAnalyzer::visit(FunctionCall const& _functionCall) +{ + if (_functionCall.annotation().kind == FunctionCallKind::FunctionCall) + { + auto functionType = dynamic_pointer_cast(_functionCall.expression().annotation().type); + solAssert(functionType, ""); + if (functionType->kind() == FunctionType::Kind::AddMod || functionType->kind() == FunctionType::Kind::MulMod) + { + solAssert(_functionCall.arguments().size() == 3, ""); + if (_functionCall.arguments()[2]->annotation().isPure) + if (auto lastArg = dynamic_pointer_cast( + ConstantEvaluator(m_errorReporter).evaluate(*(_functionCall.arguments())[2]) + )) + if (lastArg->isZero()) + m_errorReporter.typeError( + _functionCall.location(), + "Arithmetic modulo zero." + ); + } + } + return true; +} + bigint StaticAnalyzer::structureSizeEstimate(Type const& _type, set& _structsSeen) { switch (_type.category()) -- cgit v1.2.3 From be37e3a912f6d5a2a57544f60362be65b7be8284 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 12 Apr 2018 18:14:48 +0200 Subject: Stricter check for member access to "this" in constructor. --- libsolidity/analysis/StaticAnalyzer.cpp | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'libsolidity/analysis/StaticAnalyzer.cpp') diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 51aa0b28..00a581d0 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -206,10 +206,32 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) ); } - if (m_constructor && m_currentContract) - if (ContractType const* type = dynamic_cast(_memberAccess.expression().annotation().type.get())) - if (type->contractDefinition() == *m_currentContract) - m_errorReporter.warning(_memberAccess.location(), "\"this\" used in constructor."); + if (m_constructor) + { + auto const* expr = &_memberAccess.expression(); + while(expr) + { + if (auto id = dynamic_cast(expr)) + { + if (id->name() == "this") + m_errorReporter.warning( + id->location(), + "\"this\" used in constructor. " + "Note that external functions of a contract " + "cannot be called while it is being constructed."); + break; + } + else if (auto tuple = dynamic_cast(expr)) + { + if (tuple->components().size() == 1) + expr = tuple->components().front().get(); + else + break; + } + else + break; + } + } return true; } -- cgit v1.2.3