From 2101637d005884e84fddfae99550de8fc9c37eaa Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Thu, 11 Jun 2026 14:06:08 +0300 Subject: [PATCH] refactor: address clang-tidy issues --- .clang-tidy | 3 +++ src/libs/core/httpserver.cpp | 3 +-- src/libs/registry/listmodel.cpp | 13 ++++++------- src/libs/ui/docsetsdialog.cpp | 6 +++--- src/libs/util/tarixarchive.cpp | 8 ++++---- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 08ae96ea..50934b56 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -8,12 +8,15 @@ HeaderFilterRegex: 'src[/\\].*' ExcludeHeaderFilterRegex: 'src[/\\]contrib[/\\].*|.*_autogen[/\\].*' # TODO: Reevaluate -modernize-use-nodiscard. # TODO: Re-enable {cppcoreguidelines,misc}-non-private-member-variables-in-classes. +# clang-analyzer-core.StackAddressEscape: cpp-httplib stores handlers by value, but the analyzer +# reports a false escape inside the library header, where it cannot be suppressed in-source. Checks: > *, -abseil-*, -altera-*, -android-*, -bugprone-easily-swappable-parameters, + -clang-analyzer-core.StackAddressEscape, -concurrency-mt-unsafe, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-non-private-member-variables-in-classes, diff --git a/src/libs/core/httpserver.cpp b/src/libs/core/httpserver.cpp index b2e3e239..6a9e287f 100644 --- a/src/libs/core/httpserver.cpp +++ b/src/libs/core/httpserver.cpp @@ -43,7 +43,6 @@ HttpServer::HttpServer(quint16 port, QObject *parent) m_baseUrl.setHost(QString::fromLatin1(LocalHttpServerHost)); m_baseUrl.setPort(boundPort); - // NOLINTNEXTLINE(clang-analyzer-core.StackAddressEscape): false positive — cpp-httplib stores the handler by value. m_server->set_error_handler([this](const auto &req, auto &res) { // On 404, try case-insensitive path resolution. // Docsets generated on macOS (case-insensitive) may have links with mismatched case. @@ -77,7 +76,6 @@ HttpServer::HttpServer(quint16 port, QObject *parent) // Content-provider mounts share one catch-all route because cpp-httplib // cannot remove individual handlers. Directory mounts are served by // cpp-httplib before this handler is reached. - // NOLINTNEXTLINE(clang-analyzer-core.StackAddressEscape): false positive — cpp-httplib stores the handler by value. m_server->Get("/.+", [this](const auto &req, auto &res) { const QString reqPath = QString::fromStdString(req.path); const qsizetype prefixEnd = reqPath.indexOf(QLatin1Char('/'), 1); @@ -86,6 +84,7 @@ HttpServer::HttpServer(quint16 port, QObject *parent) // Hold the lock while reading so unmount cannot invalidate the provider mid-request. const QReadLocker locker(&m_mountPointsLock); + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage): Qt COW d-pointer confuses the analyzer. const auto it = m_contentProviders.constFind(prefix); if (it == m_contentProviders.constEnd()) { res.status = 404; diff --git a/src/libs/registry/listmodel.cpp b/src/libs/registry/listmodel.cpp index f9577234..ef56093f 100644 --- a/src/libs/registry/listmodel.cpp +++ b/src/libs/registry/listmodel.cpp @@ -104,16 +104,15 @@ QVariant ListModel::data(const QModelIndex &index, int role) const auto *const docset = itemInRow(index.row())->docset; QString tooltip = tr("Version: %1r%2").arg(docset->version()).arg(docset->revision()); - if (docset->hasUpdate()) { - const Docset::UpdateInfo &update = docset->update().value(); - if (update.size > 0) { + if (const auto &update = docset->update()) { + if (update->size > 0) { tooltip += QLatin1Char('\n') + tr("Update available: %1r%2 (%3)") - .arg(update.version) - .arg(update.revision) - .arg(QLocale::system().formattedDataSize(update.size)); + .arg(update->version) + .arg(update->revision) + .arg(QLocale::system().formattedDataSize(update->size)); } else { - tooltip += QLatin1Char('\n') + tr("Update available: %1r%2").arg(update.version).arg(update.revision); + tooltip += QLatin1Char('\n') + tr("Update available: %1r%2").arg(update->version).arg(update->revision); } } diff --git a/src/libs/ui/docsetsdialog.cpp b/src/libs/ui/docsetsdialog.cpp index 19e911be..e9e34298 100644 --- a/src/libs/ui/docsetsdialog.cpp +++ b/src/libs/ui/docsetsdialog.cpp @@ -429,7 +429,7 @@ void DocsetsDialog::downloadCompleted() const QString docsetName = reply->property(DocsetNameProperty).toString(); const QString docsetDirectoryName = docsetName + QLatin1String(".docset"); - QTemporaryFile *tmpFile = m_tmpFiles.value(docsetName); + const QTemporaryFile *tmpFile = m_tmpFiles.value(docsetName); if (tmpFile == nullptr) { break; // Installation has been canceled. } @@ -1036,7 +1036,7 @@ void DocsetsDialog::onTarixIndexFailed(QNetworkReply *reply) QMessageBox::NoButton, this); QPushButton *retryButton = box.addButton(QMessageBox::Retry); - QPushButton *installButton = box.addButton(tr("Install Anyway"), QMessageBox::AcceptRole); + const QPushButton *installButton = box.addButton(tr("Install Anyway"), QMessageBox::AcceptRole); box.addButton(QMessageBox::Cancel); box.setDefaultButton(retryButton); box.exec(); @@ -1056,7 +1056,7 @@ void DocsetsDialog::onTarixIndexFailed(QNetworkReply *reply) void DocsetsDialog::installDownloadedDocset(const QString &docsetName) { - QTemporaryFile *tmpFile = m_tmpFiles.value(docsetName); + const QTemporaryFile *tmpFile = m_tmpFiles.value(docsetName); if (tmpFile == nullptr) { return; } diff --git a/src/libs/util/tarixarchive.cpp b/src/libs/util/tarixarchive.cpp index b8d0f3db..17cdefee 100644 --- a/src/libs/util/tarixarchive.cpp +++ b/src/libs/util/tarixarchive.cpp @@ -12,8 +12,6 @@ #include #include -#include - namespace Zeal::Util { namespace { @@ -33,7 +31,8 @@ QByteArray inflateFrom(QFile &file, qint64 rawSize) QByteArray in(InflateChunkSize, Qt::Uninitialized); // next_out is set once; zlib advances it as it fills the output buffer. - zs.next_out = std::bit_cast(out.data()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): Bytef* is unsigned char*; conversion is defined. + zs.next_out = reinterpret_cast(out.data()); zs.avail_out = static_cast(rawSize); int rc = Z_OK; @@ -43,7 +42,8 @@ QByteArray inflateFrom(QFile &file, qint64 rawSize) break; } - zs.next_in = std::bit_cast(in.data()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + zs.next_in = reinterpret_cast(in.data()); zs.avail_in = static_cast(inSize); while (zs.avail_in > 0 && zs.avail_out > 0) {