summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@theqtcompany.com>2015-12-30 14:03:26 +0100
committerTopi Reiniƶ <topi.reinio@theqtcompany.com>2016-01-04 14:03:52 +0000
commit3c5cc414711f0d17bb32e7282eb21588947465a5 (patch)
tree8c48c332d3b6a8c9c25b1005411afdb3887a3c81
parent23fc55c4bbf3cf334ff33f1b7816c35fdc67fd93 (diff)
qdoc: Don't let a QML type be its own base type
When qdoc runs without one or more of the index files for the modules it depends on, there was a chance it could set a QML type's base type to point to the QML type itself. This resulted in an infinite loop, which crashed qdoc with a bad alloc error. qdoc has now been changed so that it refuses to set a QML type's base type to itself. Change-Id: I08e8959ddb67b2d1f3b1bf44d9dc48624bafebfa Task-number: QTBUG-50163 Reviewed-by: Martin Smith <martin.smith@theqtcompany.com>
-rw-r--r--src/qdoc/cppcodemarker.cpp6
-rw-r--r--src/qdoc/qdocdatabase.cpp6
2 files changed, 9 insertions, 3 deletions
diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp
index d4e7546e9..b0e4e823d 100644
--- a/src/qdoc/cppcodemarker.cpp
+++ b/src/qdoc/cppcodemarker.cpp
@@ -1306,6 +1306,12 @@ QList<Section> CppCodeMarker::qmlSections(QmlTypeNode* qmlTypeNode, SynopsisStyl
}
++c;
}
+ if (current->qmlBaseNode() == current) {
+ qDebug() << "qdoc internal error: circular type definition."
+ << "QML type" << current->name()
+ << "can't be its own base type";
+ break;
+ }
current = current->qmlBaseNode();
while (current) {
if (current->isAbstract())
diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp
index 1707963c8..e3331a4f0 100644
--- a/src/qdoc/qdocdatabase.cpp
+++ b/src/qdoc/qdocdatabase.cpp
@@ -1460,21 +1460,21 @@ void QDocDatabase::resolveQmlInheritance(Aggregate* root)
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(child);
if (qcn->qmlBaseNodeNotSet() && !qcn->qmlBaseName().isEmpty()) {
QmlTypeNode* bqcn = static_cast<QmlTypeNode*>(previousSearches.value(qcn->qmlBaseName()));
- if (bqcn)
+ if (bqcn && (bqcn != qcn))
qcn->setQmlBaseNode(bqcn);
else {
if (!qcn->importList().isEmpty()) {
const ImportList& imports = qcn->importList();
for (int i=0; i<imports.size(); ++i) {
bqcn = findQmlType(imports[i], qcn->qmlBaseName());
- if (bqcn)
+ if (bqcn && (bqcn != qcn))
break;
}
}
if (bqcn == 0) {
bqcn = findQmlType(QString(), qcn->qmlBaseName());
}
- if (bqcn) {
+ if (bqcn && (bqcn != qcn)) {
qcn->setQmlBaseNode(bqcn);
previousSearches.insert(qcn->qmlBaseName(), bqcn);
}