diff options
author | Leandro Melo <leandro.melo@nokia.com> | 2010-08-05 11:41:21 +0200 |
---|---|---|
committer | Leandro Melo <leandro.melo@nokia.com> | 2010-08-05 11:46:44 +0200 |
commit | b61dbac6ff78b08318049e77f57965c9005bdde3 (patch) | |
tree | 2fb48515c683f97422dcc7821a1f33052bf4f177 /src/plugins/cppeditor/cpphoverhandler.cpp | |
parent | 6c009f19cd71286767eb344bc30b60e485144bc9 (diff) | |
download | qt-creator-b61dbac6ff78b08318049e77f57965c9005bdde3.tar.gz |
Fix potential endless recursion in C++ hover handler.
To catch cases of invalid code like this:
struct A : B {};
struct B : A {};
Reviewed-by: Roberto Raggi
Diffstat (limited to 'src/plugins/cppeditor/cpphoverhandler.cpp')
-rw-r--r-- | src/plugins/cppeditor/cpphoverhandler.cpp | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index 6efc3ae1b1..d90162e608 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -49,6 +49,7 @@ #include <cplusplus/LookupContext.h> #include <cplusplus/LookupItem.h> +#include <QtCore/QSet> #include <QtCore/QDir> #include <QtCore/QFileInfo> #include <QtCore/QtAlgorithms> @@ -82,24 +83,30 @@ namespace { } } - void buildClassHierarchyHelper(Symbol *symbol, + void buildClassHierarchyHelper(ClassOrNamespace *classSymbol, const LookupContext &context, const Overview &overview, - QList<QStringList> *hierarchy) { - if (ClassOrNamespace *classSymbol = context.lookupType(symbol)) { - const QList<ClassOrNamespace *> &bases = classSymbol->usings(); - foreach (ClassOrNamespace *baseClass, bases) { - const QList<Symbol *> &symbols = baseClass->symbols(); - foreach (Symbol *baseSymbol, symbols) { - if (baseSymbol->isClass()) { - const QString &qualifiedName = overview.prettyName( - LookupContext::fullyQualifiedName(baseSymbol)); - if (!qualifiedName.isEmpty()) { - hierarchy->back().append(qualifiedName); - buildClassHierarchyHelper(baseSymbol, context, overview, hierarchy); - hierarchy->append(hierarchy->back()); - hierarchy->back().removeLast(); - } + QList<QStringList> *hierarchy, + QSet<ClassOrNamespace *> *visited) { + visited->insert(classSymbol); + const QList<ClassOrNamespace *> &bases = classSymbol->usings(); + foreach (ClassOrNamespace *baseClass, bases) { + const QList<Symbol *> &symbols = baseClass->symbols(); + foreach (Symbol *baseSymbol, symbols) { + if (baseSymbol->isClass() && ( + classSymbol = context.lookupType(baseSymbol)) && + !visited->contains(classSymbol)) { + const QString &qualifiedName = overview.prettyName( + LookupContext::fullyQualifiedName(baseSymbol)); + if (!qualifiedName.isEmpty()) { + hierarchy->back().append(qualifiedName); + buildClassHierarchyHelper(classSymbol, + context, + overview, + hierarchy, + visited); + hierarchy->append(hierarchy->back()); + hierarchy->back().removeLast(); } } } @@ -110,10 +117,12 @@ namespace { const LookupContext &context, const Overview &overview, QList<QStringList> *hierarchy) { - if (hierarchy->isEmpty()) + if (ClassOrNamespace *classSymbol = context.lookupType(symbol)) { hierarchy->append(QStringList()); - buildClassHierarchyHelper(symbol, context, overview, hierarchy); - hierarchy->removeLast(); + QSet<ClassOrNamespace *> visited; + buildClassHierarchyHelper(classSymbol, context, overview, hierarchy, &visited); + hierarchy->removeLast(); + } } struct ClassHierarchyComp |