aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis/StaticAnalyzer.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-08-25 02:50:37 +0800
committerGitHub <noreply@github.com>2017-08-25 02:50:37 +0800
commitd7661dd97460250b4e1127b9e7ea91e116143780 (patch)
tree0d909e7aeec373b0559b9d80f8ae9a9e03bdd92b /libsolidity/analysis/StaticAnalyzer.cpp
parentbbb8e64fbee632d1594f6c132b1174591b961207 (diff)
parentdd67e5966f41be0b2ef52041ea726930af74f7e9 (diff)
downloaddexon-solidity-d7661dd97460250b4e1127b9e7ea91e116143780.tar
dexon-solidity-d7661dd97460250b4e1127b9e7ea91e116143780.tar.gz
dexon-solidity-d7661dd97460250b4e1127b9e7ea91e116143780.tar.bz2
dexon-solidity-d7661dd97460250b4e1127b9e7ea91e116143780.tar.lz
dexon-solidity-d7661dd97460250b4e1127b9e7ea91e116143780.tar.xz
dexon-solidity-d7661dd97460250b4e1127b9e7ea91e116143780.tar.zst
dexon-solidity-d7661dd97460250b4e1127b9e7ea91e116143780.zip
Merge pull request #2802 from ethereum/develop
Merge develop into release for 0.4.16
Diffstat (limited to 'libsolidity/analysis/StaticAnalyzer.cpp')
-rw-r--r--libsolidity/analysis/StaticAnalyzer.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp
index 46477e1e..2f130414 100644
--- a/libsolidity/analysis/StaticAnalyzer.cpp
+++ b/libsolidity/analysis/StaticAnalyzer.cpp
@@ -57,6 +57,8 @@ bool StaticAnalyzer::visit(FunctionDefinition const& _function)
solAssert(m_localVarUseCount.empty(), "");
m_nonPayablePublic = _function.isPublic() && !_function.isPayable();
m_constructor = _function.isConstructor();
+ if (_function.stateMutability() == StateMutability::Pure)
+ m_errorReporter.warning(_function.location(), "Function is marked pure. Be careful, pureness is not enforced yet.");
return true;
}
@@ -92,6 +94,17 @@ bool StaticAnalyzer::visit(VariableDeclaration const& _variable)
// This is not a no-op, the entry might pre-exist.
m_localVarUseCount[&_variable] += 0;
}
+ else if (_variable.isStateVariable())
+ {
+ set<StructDefinition const*> structsSeen;
+ if (structureSizeEstimate(*_variable.type(), structsSeen) >= bigint(1) << 64)
+ m_errorReporter.warning(
+ _variable.location(),
+ "Variable covers a large part of storage and thus makes collisions likely. "
+ "Either use mappings or dynamic arrays and allow their size to be increased only "
+ "in small quantities per transaction."
+ );
+ }
return true;
}
@@ -160,3 +173,34 @@ bool StaticAnalyzer::visit(InlineAssembly const& _inlineAssembly)
return true;
}
+
+bigint StaticAnalyzer::structureSizeEstimate(Type const& _type, set<StructDefinition const*>& _structsSeen)
+{
+ switch (_type.category())
+ {
+ case Type::Category::Array:
+ {
+ auto const& t = dynamic_cast<ArrayType const&>(_type);
+ return structureSizeEstimate(*t.baseType(), _structsSeen) * (t.isDynamicallySized() ? 1 : t.length());
+ }
+ case Type::Category::Struct:
+ {
+ auto const& t = dynamic_cast<StructType const&>(_type);
+ bigint size = 1;
+ if (!_structsSeen.count(&t.structDefinition()))
+ {
+ _structsSeen.insert(&t.structDefinition());
+ for (auto const& m: t.members(nullptr))
+ size += structureSizeEstimate(*m.type, _structsSeen);
+ }
+ return size;
+ }
+ case Type::Category::Mapping:
+ {
+ return structureSizeEstimate(*dynamic_cast<MappingType const&>(_type).valueType(), _structsSeen);
+ }
+ default:
+ break;
+ }
+ return bigint(1);
+}