diff options
| author | Joerg Bornemann <joerg.bornemann@digia.com> | 2013-10-14 11:34:42 +0200 |
|---|---|---|
| committer | Christian Kandeler <christian.kandeler@digia.com> | 2013-10-14 17:03:17 +0200 |
| commit | c939d3bb79619229626ccd02ea7deabe5debf060 (patch) | |
| tree | cd69e3f8b699665aad9d7d2e80323f2ab08a6924 /src/lib/buildgraph/rulegraph.cpp | |
| parent | 3343f681c71f821aa9460f184c30e5ecf3781776 (diff) | |
| download | qbs-c939d3bb79619229626ccd02ea7deabe5debf060.tar.gz | |
detect cycles in rule dependencies
This fixes a stack overflow that occurred when having cycles in rule
dependencies.
Task-number: QBS-396
Change-Id: I1907ef66d74340c090b09be72d2352892baca986
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
Diffstat (limited to 'src/lib/buildgraph/rulegraph.cpp')
| -rw-r--r-- | src/lib/buildgraph/rulegraph.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/lib/buildgraph/rulegraph.cpp b/src/lib/buildgraph/rulegraph.cpp index c2653ad7e..b33c8891d 100644 --- a/src/lib/buildgraph/rulegraph.cpp +++ b/src/lib/buildgraph/rulegraph.cpp @@ -29,6 +29,7 @@ #include "rulegraph.h" #include <language/language.h> +#include <logging/translator.h> #include <tools/error.h> namespace qbs { @@ -79,7 +80,9 @@ QList<RuleConstPtr> RuleGraph::topSorted() QList<RuleConstPtr> result; foreach (int rootIndex, rootRules) { RuleConstPtr rule = m_artifacts.at(rootIndex); - result.append(topSort(rule)); + QSet<const Rule *> seenRules; + QList<const Rule *> rulePath; + result.append(topSort(rule, &seenRules, &rulePath)); } // remove duplicates from the result of our post-order traversal @@ -182,13 +185,28 @@ void RuleGraph::removeSiblings(const Rule *rule) } } -QList<RuleConstPtr> RuleGraph::topSort(const RuleConstPtr &rule) +QList<RuleConstPtr> RuleGraph::topSort(const RuleConstPtr &rule, QSet<const Rule *> *seenRules, + QList<const Rule *> *rulePath) { + if (seenRules->contains(rule.data())) { + QString pathstr; + foreach (const Rule *r, *rulePath) { + pathstr += QLatin1Char('\n') + r->toString() + QLatin1Char('\t') + + r->script->location.toString(); + } + throw ErrorInfo(Tr::tr("Cycle detected in rule dependencies: %1").arg(pathstr)); + } + + seenRules->insert(rule.data()); + rulePath->prepend(rule.data()); + QList<RuleConstPtr> result; foreach (int childIndex, m_children.at(rule->ruleGraphId)) - result.append(topSort(m_artifacts.at(childIndex))); + result.append(topSort(m_artifacts.at(childIndex), seenRules, rulePath)); result.append(rule); + seenRules->remove(rule.data()); + rulePath->removeFirst(); return result; } |
