QmakeProjectManager: Try harder not to access nodes of in-parse project

For extra safety, do not touch the project nodes if any build system of
any build configuration is currently parsing.
This is a bit of a stab in the dark, as I cannot reproduce the crash
described in the linked bug report.

Task-number: QTCREATORBUG-23597
Change-Id: Ie62a94232e89d8fba5866ea3572535e2ab209924
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-03-03 14:57:21 +01:00
parent 5683f2df85
commit ae0d2bd1ac
3 changed files with 20 additions and 7 deletions

View File

@@ -320,7 +320,7 @@ bool Project::removeTarget(Target *target)
return true;
}
QList<Target *> Project::targets() const
const QList<Target *> Project::targets() const
{
return Utils::toRawPointer<QList>(d->m_targets);
}

View File

@@ -106,7 +106,7 @@ public:
Target *addTargetForKit(Kit *kit);
bool removeTarget(Target *target);
QList<Target *> targets() const;
const QList<Target *> targets() const;
// Note: activeTarget can be 0 (if no targets are defined).
Target *activeTarget() const;
Target *target(Core::Id id) const;

View File

@@ -37,6 +37,7 @@
#include <coreplugin/fileiconprovider.h>
#include <extensionsystem/pluginmanager.h>
#include <qtsupport/qtsupportconstants.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <projectexplorer/session.h>
@@ -85,12 +86,24 @@ QString ProFileEditorWidget::checkForPrfFile(const QString &baseName) const
{
const FilePath projectFile = textDocument()->filePath();
const QmakePriFileNode *projectNode = nullptr;
// FIXME: Remove this check once project nodes are fully "static".
for (const Project * const project : SessionManager::projects()) {
if (Target *t = project->activeTarget()) {
if (t->buildSystem()->isParsing())
continue;
static const auto isParsing = [](const Project *project) {
for (const Target * const t : project->targets()) {
for (const BuildConfiguration * const bc : t->buildConfigurations()) {
if (bc->buildSystem()->isParsing())
return true;
}
projectNode = dynamic_cast<const QmakePriFileNode *>(project->rootProjectNode()
}
return false;
};
if (isParsing(project))
continue;
ProjectNode * const rootNode = project->rootProjectNode();
QTC_ASSERT(rootNode, continue);
projectNode = dynamic_cast<const QmakePriFileNode *>(rootNode
->findProjectNode([&projectFile](const ProjectNode *pn) {
return pn->filePath() == projectFile;
}));