aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis/PostTypeChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/analysis/PostTypeChecker.cpp')
-rw-r--r--libsolidity/analysis/PostTypeChecker.cpp36
1 files changed, 21 insertions, 15 deletions
diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp
index fbc72e52..19d0b708 100644
--- a/libsolidity/analysis/PostTypeChecker.cpp
+++ b/libsolidity/analysis/PostTypeChecker.cpp
@@ -21,6 +21,8 @@
#include <libsolidity/interface/ErrorReporter.h>
#include <libsolidity/interface/Version.h>
+#include <libdevcore/Algorithms.h>
+
#include <boost/range/adaptor/map.hpp>
#include <memory>
@@ -47,7 +49,7 @@ void PostTypeChecker::endVisit(ContractDefinition const&)
{
solAssert(!m_currentConstVariable, "");
for (auto declaration: m_constVariables)
- if (auto identifier = findCycle(declaration))
+ if (auto identifier = findCycle(*declaration))
m_errorReporter.typeError(
declaration->location(),
"The value of the constant " + declaration->name() +
@@ -87,20 +89,24 @@ bool PostTypeChecker::visit(Identifier const& _identifier)
return true;
}
-VariableDeclaration const* PostTypeChecker::findCycle(
- VariableDeclaration const* _startingFrom,
- set<VariableDeclaration const*> const& _seen
-)
+VariableDeclaration const* PostTypeChecker::findCycle(VariableDeclaration const& _startingFrom)
{
- if (_seen.count(_startingFrom))
- return _startingFrom;
- else if (m_constVariableDependencies.count(_startingFrom))
+ auto visitor = [&](VariableDeclaration const& _variable, CycleDetector<VariableDeclaration>& _cycleDetector)
{
- set<VariableDeclaration const*> seen(_seen);
- seen.insert(_startingFrom);
- for (auto v: m_constVariableDependencies[_startingFrom])
- if (findCycle(v, seen))
- return v;
- }
- return nullptr;
+ // Iterating through the dependencies needs to be deterministic and thus cannot
+ // depend on the memory layout.
+ // Because of that, we sort by AST node id.
+ vector<VariableDeclaration const*> dependencies(
+ m_constVariableDependencies[&_variable].begin(),
+ m_constVariableDependencies[&_variable].end()
+ );
+ sort(dependencies.begin(), dependencies.end(), [](VariableDeclaration const* _a, VariableDeclaration const* _b) -> bool
+ {
+ return _a->id() < _b->id();
+ });
+ for (auto v: dependencies)
+ if (_cycleDetector.run(*v))
+ return;
+ };
+ return CycleDetector<VariableDeclaration>(visitor).run(_startingFrom);
}