ClangCodeModel: Fix callback handling when following symbols

Make sure emitDone() is atomic with running the callback, so in case the
latter starts an event loop of its own, we won't be overtaken by
incoming signals, deleting the object from under us.

Task-number: QTCREATORBUG-27910
Change-Id: I586d7609974662bf391b12041f416aaa2a973ecb
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Christian Kandeler
2022-07-18 18:08:01 +02:00
committed by Eike Ziller
parent b2407dbde5
commit 5c341854e0
2 changed files with 11 additions and 13 deletions

View File

@@ -146,14 +146,14 @@ ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, const QTextCursor &
openInSplit))
{
// Abort if the user does something else with the document in the meantime.
connect(document, &TextDocument::contentsChanged, this, &ClangdFollowSymbol::emitDone,
connect(document, &TextDocument::contentsChanged, this, [this] { emitDone(); },
Qt::QueuedConnection);
if (editorWidget) {
connect(editorWidget, &CppEditorWidget::cursorPositionChanged,
this, &ClangdFollowSymbol::emitDone, Qt::QueuedConnection);
this, [this] { emitDone(); }, Qt::QueuedConnection);
}
d->focusChangedConnection = connect(qApp, &QApplication::focusChanged,
this, &ClangdFollowSymbol::emitDone, Qt::QueuedConnection);
this, [this] { emitDone(); }, Qt::QueuedConnection);
// Step 1: Follow the symbol via "Go to Definition". At the same time, request the
// AST node corresponding to the cursor position, so we can find out whether
@@ -205,12 +205,14 @@ void ClangdFollowSymbol::clear()
d->pendingGotoDefRequests.clear();
}
void ClangdFollowSymbol::emitDone()
void ClangdFollowSymbol::emitDone(const Link &link)
{
if (d->done)
return;
d->done = true;
if (link.hasValidTarget())
d->callback(link);
emit done();
}
@@ -246,14 +248,12 @@ void ClangdFollowSymbol::Private::handleDocumentInfoResults()
// If something went wrong, we just follow the original link.
if (symbolsToDisplay.isEmpty()) {
callback(defLink);
q->emitDone();
q->emitDone(defLink);
return;
}
if (symbolsToDisplay.size() == 1) {
callback(symbolsToDisplay.first().second);
q->emitDone();
q->emitDone(symbolsToDisplay.first().second);
return;
}
@@ -382,8 +382,7 @@ void ClangdFollowSymbol::Private::handleGotoDefinitionResult()
// No dis-ambiguation necessary. Call back with the link and finish.
if (!defLinkIsAmbiguous()) {
callback(defLink);
q->emitDone();
q->emitDone(defLink);
return;
}
@@ -416,8 +415,7 @@ void ClangdFollowSymbol::Private::handleGotoImplementationResult(
// We didn't find any further candidates, so jump to the original definition link.
if (allLinks.size() == 1 && pendingGotoImplRequests.isEmpty()) {
callback(allLinks.first());
q->emitDone();
q->emitDone(allLinks.first());
return;
}

View File

@@ -55,7 +55,7 @@ signals:
void done();
private:
void emitDone();
void emitDone(const Utils::Link &link = {});
class VirtualFunctionAssistProcessor;
class VirtualFunctionAssistProvider;