Clang: Fix crash after cancelled completion request

Amends

  commit 755de9f86a
  Editor: delete processor after canceling

Ensure to update the bookkeeping in BackendReceiver on

  CodeAssistantPrivate::cancelCurrentRequest()

as otherwise we run into a use-after-free.

Change-Id: Ic5abdc9d743dc0b76eb050a9e3e00f85d2c5bc96
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2020-05-19 07:44:46 +02:00
parent bd3a356ce9
commit a35832385c
6 changed files with 31 additions and 2 deletions

View File

@@ -513,5 +513,10 @@ void BackendCommunicator::requestCompletions(ClangCompletionAssistProcessor *ass
m_receiver.addExpectedCompletionsMessage(message.ticketNumber, assistProcessor); m_receiver.addExpectedCompletionsMessage(message.ticketNumber, assistProcessor);
} }
void BackendCommunicator::cancelCompletions(TextEditor::IAssistProcessor *processor)
{
m_receiver.cancelProcessor(processor);
}
} // namespace Internal } // namespace Internal
} // namespace ClangCodeModel } // namespace ClangCodeModel

View File

@@ -43,6 +43,8 @@ class IEditor;
class IDocument; class IDocument;
} }
namespace TextEditor { class IAssistProcessor; }
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Internal { namespace Internal {
@@ -88,6 +90,7 @@ public:
quint32 column, quint32 column,
qint32 funcNameStartLine = -1, qint32 funcNameStartLine = -1,
qint32 funcNameStartColumn = -1); qint32 funcNameStartColumn = -1);
void cancelCompletions(TextEditor::IAssistProcessor *processor);
void requestAnnotations(const ClangBackEnd::FileContainer &fileContainer); void requestAnnotations(const ClangBackEnd::FileContainer &fileContainer);
QFuture<CppTools::CursorInfo> requestReferences( QFuture<CppTools::CursorInfo> requestReferences(
const FileContainer &fileContainer, const FileContainer &fileContainer,

View File

@@ -84,6 +84,18 @@ void BackendReceiver::addExpectedCompletionsMessage(
m_assistProcessorsTable.insert(ticket, processor); m_assistProcessorsTable.insert(ticket, processor);
} }
void BackendReceiver::cancelProcessor(TextEditor::IAssistProcessor *processor)
{
for (auto it = m_assistProcessorsTable.cbegin(), end = m_assistProcessorsTable.cend();
it != end; ++it)
{
if (it.value() == processor) {
m_assistProcessorsTable.erase(it);
return;
}
}
}
void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget) void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget)
{ {
QList<quint64> toRemove; QList<quint64> toRemove;

View File

@@ -35,7 +35,10 @@
#include <QPointer> #include <QPointer>
#include <QTextDocument> #include <QTextDocument>
namespace TextEditor { class TextEditorWidget; } namespace TextEditor {
class IAssistProcessor;
class TextEditorWidget;
} // namespace TextEditor
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Internal { namespace Internal {
@@ -52,6 +55,7 @@ public:
void setAliveHandler(const AliveHandler &handler); void setAliveHandler(const AliveHandler &handler);
void addExpectedCompletionsMessage(quint64 ticket, ClangCompletionAssistProcessor *processor); void addExpectedCompletionsMessage(quint64 ticket, ClangCompletionAssistProcessor *processor);
void cancelProcessor(TextEditor::IAssistProcessor *processor);
void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget); void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);
QFuture<CppTools::CursorInfo> QFuture<CppTools::CursorInfo>

View File

@@ -697,6 +697,10 @@ IAssistProposal *ClangCompletionAssistProcessor::createFunctionHintProposal(
return new FunctionHintProposal(m_positionForProposal, model); return new FunctionHintProposal(m_positionForProposal, model);
} }
void ClangCompletionAssistProcessor::cancel()
{
m_interface->communicator().cancelCompletions(this);
}
} // namespace Internal } // namespace Internal
} // namespace ClangCodeModel } // namespace ClangCodeModel

View File

@@ -56,6 +56,7 @@ public:
const TextEditor::TextEditorWidget *textEditorWidget() const; const TextEditor::TextEditorWidget *textEditorWidget() const;
private: private:
void cancel() override;
TextEditor::IAssistProposal *startCompletionHelper(); TextEditor::IAssistProposal *startCompletionHelper();
int startOfOperator(int pos, unsigned *kind, bool wantFunctionCall) const; int startOfOperator(int pos, unsigned *kind, bool wantFunctionCall) const;
int findStartOfName(int pos = -1) const; int findStartOfName(int pos = -1) const;