CppEditor: Do not call CanonicalSymbol::operator() on a temporary

Somewhat surprisingly, the returned symbol is owned by the object.
Prevent future instances of this mistake by making the function lvalue-
ref-qualified.

Change-Id: Id903ce160986d60cada55e181ad2f6eb2c7488da
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2023-09-22 15:20:32 +02:00
parent ee51a1cbdf
commit 92f76a3355
3 changed files with 27 additions and 10 deletions

View File

@@ -54,7 +54,7 @@ Scope *CanonicalSymbol::getScopeAndExpression(const QTextCursor &cursor, QString
return m_document->scopeAt(line, column); return m_document->scopeAt(line, column);
} }
Symbol *CanonicalSymbol::operator()(const QTextCursor &cursor) Symbol *CanonicalSymbol::operator()(const QTextCursor &cursor) &
{ {
QString code; QString code;

View File

@@ -21,7 +21,7 @@ public:
CPlusPlus::Scope *getScopeAndExpression(const QTextCursor &cursor, QString *code); CPlusPlus::Scope *getScopeAndExpression(const QTextCursor &cursor, QString *code);
CPlusPlus::Symbol *operator()(const QTextCursor &cursor); CPlusPlus::Symbol *operator()(const QTextCursor &cursor) &;
CPlusPlus::Symbol *operator()(CPlusPlus::Scope *scope, const QString &code); CPlusPlus::Symbol *operator()(CPlusPlus::Scope *scope, const QString &code);
public: public:

View File

@@ -49,6 +49,7 @@
#include <QTextCursor> #include <QTextCursor>
#include <QTextDocument> #include <QTextDocument>
#include <optional>
#include <vector> #include <vector>
using namespace CPlusPlus; using namespace CPlusPlus;
@@ -687,8 +688,14 @@ SearchResultItems symbolOccurrencesInDeclarationComments(
} }
}; };
struct ClassInfo {
FilePath filePath;
int startOffset = -1;
int endOffset = -1;
};
std::optional<ClassInfo> classInfo;
// Collect comment blocks associated with replace locations. // Collect comment blocks associated with replace locations.
Symbol *canonicalSymbol = nullptr;
for (const SearchResultItem &item : symbolOccurrencesInCode) { for (const SearchResultItem &item : symbolOccurrencesInCode) {
const FilePath filePath = FilePath::fromUserInput(item.path().last()); const FilePath filePath = FilePath::fromUserInput(item.path().last());
auto &[doc, content, cppDoc, allCommentTokens] = fileData(filePath); auto &[doc, content, cppDoc, allCommentTokens] = fileData(filePath);
@@ -705,10 +712,19 @@ SearchResultItems symbolOccurrencesInDeclarationComments(
for (const Token &tok : commentTokens) for (const Token &tok : commentTokens)
addToken(allCommentTokens, tok); addToken(allCommentTokens, tok);
if (!canonicalSymbol) { if (!classInfo) {
QTextCursor cursor(doc); QTextCursor cursor(doc);
cursor.setPosition(Text::positionInText(doc, range.begin.line, range.begin.column + 1)); cursor.setPosition(Text::positionInText(doc, range.begin.line, range.begin.column + 1));
canonicalSymbol = Internal::CanonicalSymbol(cppDoc, snapshot)(cursor); Internal::CanonicalSymbol cs(cppDoc, snapshot);
Symbol * const canonicalSymbol = cs(cursor);
if (canonicalSymbol) {
classInfo.emplace();
if (Class * const klass = canonicalSymbol->asClass()) {
classInfo->filePath = canonicalSymbol->filePath();
classInfo->startOffset = klass->startOffset();
classInfo->endOffset = klass->endOffset();
}
}
} }
// We hook in between the end of the "regular" search and (possibly non-interactive) // We hook in between the end of the "regular" search and (possibly non-interactive)
@@ -722,14 +738,14 @@ SearchResultItems symbolOccurrencesInDeclarationComments(
} }
// If the symbol is a class, collect all comment blocks in the class body. // If the symbol is a class, collect all comment blocks in the class body.
if (Class * const klass = canonicalSymbol ? canonicalSymbol->asClass() : nullptr) { if (classInfo && !classInfo->filePath.isEmpty()) {
auto &[_1, _2, symbolCppDoc, commentTokens] = fileData(canonicalSymbol->filePath()); auto &[_1, _2, symbolCppDoc, commentTokens] = fileData(classInfo->filePath);
TranslationUnit * const tu = symbolCppDoc->translationUnit(); TranslationUnit * const tu = symbolCppDoc->translationUnit();
for (int i = 0; i < tu->commentCount(); ++i) { for (int i = 0; i < tu->commentCount(); ++i) {
const Token &tok = tu->commentAt(i); const Token &tok = tu->commentAt(i);
if (tok.bytesBegin() < klass->startOffset()) if (tok.bytesBegin() < classInfo->startOffset)
continue; continue;
if (tok.bytesBegin() >= klass->endOffset()) if (tok.bytesBegin() >= classInfo->endOffset)
break; break;
addToken(commentTokens, tok); addToken(commentTokens, tok);
} }
@@ -806,7 +822,8 @@ QList<Text::Range> symbolOccurrencesInDeclarationComments(CppEditorWidget *edito
const Document::Ptr &cppDoc = semanticInfo.doc; const Document::Ptr &cppDoc = semanticInfo.doc;
if (!cppDoc) if (!cppDoc)
return {}; return {};
const Symbol * const symbol = Internal::CanonicalSymbol(cppDoc, semanticInfo.snapshot)(cursor); Internal::CanonicalSymbol cs(cppDoc, semanticInfo.snapshot);
const Symbol * const symbol = cs(cursor);
if (!symbol || !symbol->asArgument()) if (!symbol || !symbol->asArgument())
return {}; return {};
const QTextDocument * const textDoc = editorWidget->textDocument()->document(); const QTextDocument * const textDoc = editorWidget->textDocument()->document();