[llvm-branch-commits] [clang-tools-extra] release/22.x: [clang-tidy] Emit warning when user is using deprecated `zircon` checks (#189522) (PR #191809)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Apr 13 06:02:37 PDT 2026


https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/191809

Backport b9d6efebf9c6527c389868caa4dfcbdc0b8078a5

Requested by: @zeyi2

>From ddca34f5e85b3febcf212850433bfdd7c8b2d38d Mon Sep 17 00:00:00 2001
From: Zeyi Xu <mitchell.xu2 at gmail.com>
Date: Mon, 13 Apr 2026 20:43:40 +0800
Subject: [PATCH] [clang-tidy] Emit warning when user is using deprecated
 `zircon` checks (#189522)

Add `utils::diagDeprecatedCheckAlias` so checks can detect whether they
are running under a deprecated name without enabling the new names.

This commit also comes with an example with `zircon` module. It is
deprecated in 22 release but we didn't provide a note for it before.

(cherry picked from commit b9d6efebf9c6527c389868caa4dfcbdc0b8078a5)
---
 .../fuchsia/TemporaryObjectsCheck.cpp         |  13 ++
 .../fuchsia/TemporaryObjectsCheck.h           |   4 +-
 .../clang-tidy/utils/CheckUtils.h             |  26 ++++
 .../temporary-objects-deprecated-alias.cpp    |  18 +++
 .../clang-tidy/ClangTidyOptionsTest.cpp       | 118 ++++++++++++++++++
 5 files changed, 176 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/utils/CheckUtils.h
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/fuchsia/temporary-objects-deprecated-alias.cpp

diff --git a/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp
index 3acd5fb555532..2fa83b41869ea 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "TemporaryObjectsCheck.h"
+#include "../utils/CheckUtils.h"
 #include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -19,6 +20,9 @@ namespace clang::tidy::fuchsia {
 
 namespace {
 
+constexpr llvm::StringLiteral DeprecatedCheckName = "zircon-temporary-objects";
+constexpr llvm::StringLiteral CanonicalCheckName = "fuchsia-temporary-objects";
+
 AST_MATCHER_P(CXXRecordDecl, matchesAnyName, ArrayRef<StringRef>, Names) {
   const std::string QualifiedName = Node.getQualifiedNameAsString();
   return llvm::is_contained(Names, QualifiedName);
@@ -26,6 +30,15 @@ AST_MATCHER_P(CXXRecordDecl, matchesAnyName, ArrayRef<StringRef>, Names) {
 
 } // namespace
 
+TemporaryObjectsCheck::TemporaryObjectsCheck(StringRef Name,
+                                             ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      Names(utils::options::parseStringList(Options.get("Names", ""))) {
+  if (Name == DeprecatedCheckName)
+    utils::diagDeprecatedCheckAlias(*this, *Context, DeprecatedCheckName,
+                                    CanonicalCheckName);
+}
+
 void TemporaryObjectsCheck::registerMatchers(MatchFinder *Finder) {
   // Matcher for default constructors.
   Finder->addMatcher(
diff --git a/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.h b/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.h
index 805dae4d577d8..74ab2a1be401c 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.h
+++ b/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.h
@@ -21,9 +21,7 @@ namespace clang::tidy::fuchsia {
 /// https://clang.llvm.org/extra/clang-tidy/checks/fuchsia/temporary-objects.html
 class TemporaryObjectsCheck : public ClangTidyCheck {
 public:
-  TemporaryObjectsCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context),
-        Names(utils::options::parseStringList(Options.get("Names", ""))) {}
+  TemporaryObjectsCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus;
   }
diff --git a/clang-tools-extra/clang-tidy/utils/CheckUtils.h b/clang-tools-extra/clang-tidy/utils/CheckUtils.h
new file mode 100644
index 0000000000000..af4821ea13520
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/utils/CheckUtils.h
@@ -0,0 +1,26 @@
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_CHECKUTILS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_CHECKUTILS_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::utils {
+
+/// Emits a configuration diagnostic when a deprecated check alias is enabled
+/// and the canonical check name is not also enabled.
+inline void diagDeprecatedCheckAlias(ClangTidyCheck &Check,
+                                     const ClangTidyContext &Context,
+                                     StringRef DeprecatedName,
+                                     StringRef CanonicalName) {
+  if (!Context.isCheckEnabled(DeprecatedName) ||
+      Context.isCheckEnabled(CanonicalName))
+    return;
+
+  Check.configurationDiag(
+      "'%0' check is deprecated and will be removed in a future release; "
+      "consider using '%1' instead")
+      << DeprecatedName << CanonicalName;
+}
+
+} // namespace clang::tidy::utils
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_CHECKUTILS_H
diff --git a/clang-tools-extra/test/clang-tidy/checkers/fuchsia/temporary-objects-deprecated-alias.cpp b/clang-tools-extra/test/clang-tidy/checkers/fuchsia/temporary-objects-deprecated-alias.cpp
new file mode 100644
index 0000000000000..301cae523bf4e
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/fuchsia/temporary-objects-deprecated-alias.cpp
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s zircon-temporary-objects %t -- \
+// RUN:   -config="{CheckOptions: {zircon-temporary-objects.Names: 'Foo'}}"
+// RUN: %check_clang_tidy -check-suffix=BOTH %s \
+// RUN:   zircon-temporary-objects,fuchsia-temporary-objects %t -- \
+// RUN:   -config="{CheckOptions: {zircon-temporary-objects.Names: 'Foo', \
+// RUN:                            fuchsia-temporary-objects.Names: 'Foo'}}"
+
+class Foo {
+public:
+  Foo() = default;
+};
+
+void f() {
+  Foo();
+  // CHECK-MESSAGES: warning: 'zircon-temporary-objects' check is deprecated and will be removed in a future release; consider using 'fuchsia-temporary-objects' instead [clang-tidy-config]
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: creating a temporary object of type 'Foo' is prohibited [zircon-temporary-objects]
+  // CHECK-MESSAGES-BOTH: :[[@LINE-3]]:3: warning: creating a temporary object of type 'Foo' is prohibited
+}
diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
index aee3313f2263b..3f86f65c1ce65 100644
--- a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
+++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
@@ -1,6 +1,7 @@
 #include "ClangTidyOptions.h"
 #include "ClangTidyCheck.h"
 #include "ClangTidyDiagnosticConsumer.h"
+#include "utils/CheckUtils.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Testing/Annotations/Annotations.h"
@@ -359,6 +360,123 @@ TEST(CheckOptionsValidation, MissingOptions) {
   EXPECT_TRUE(DiagConsumer.take().empty());
 }
 
+TEST(CheckOptionsValidation, DeprecatedAliasUtils) {
+  ClangTidyOptions Options;
+  Options.Checks = "performance-faster-string-find";
+
+  ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
+      ClangTidyGlobalOptions(), Options));
+  ClangTidyDiagnosticConsumer DiagConsumer(Context);
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(DiagnosticIDs::create(), *DiagOpts, &DiagConsumer,
+                       false);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
+
+  TestCheck TestCheck(&Context);
+  utils::diagDeprecatedCheckAlias(TestCheck, Context,
+                                  "performance-faster-string-find",
+                                  "performance-prefer-single-char-overloads");
+
+  EXPECT_THAT(
+      DiagConsumer.take(),
+      ElementsAre(
+          AllOf(ToolDiagMessage(
+                    "'performance-faster-string-find' check is deprecated and "
+                    "will be removed in a future release; consider using "
+                    "'performance-prefer-single-char-overloads' instead"),
+                ToolDiagLevel(Warning))));
+}
+
+TEST(CheckOptionsValidation, DeprecatedAliasUtilsDisabledByCanonicalCheck) {
+  ClangTidyOptions Options;
+  Options.Checks =
+      "performance-faster-string-find,performance-prefer-single-char-overloads";
+
+  ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
+      ClangTidyGlobalOptions(), Options));
+  ClangTidyDiagnosticConsumer DiagConsumer(Context);
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(DiagnosticIDs::create(), *DiagOpts, &DiagConsumer,
+                       false);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
+
+  TestCheck TestCheck(&Context);
+  utils::diagDeprecatedCheckAlias(TestCheck, Context,
+                                  "performance-faster-string-find",
+                                  "performance-prefer-single-char-overloads");
+
+  EXPECT_TRUE(DiagConsumer.take().empty());
+}
+
+TEST(CheckOptionsValidation, DeprecatedAliasUtilsEnabledByWildcardAlias) {
+  ClangTidyOptions Options;
+  Options.Checks = "performance-faster*";
+
+  ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
+      ClangTidyGlobalOptions(), Options));
+  ClangTidyDiagnosticConsumer DiagConsumer(Context);
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(DiagnosticIDs::create(), *DiagOpts, &DiagConsumer,
+                       false);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
+
+  TestCheck TestCheck(&Context);
+  utils::diagDeprecatedCheckAlias(TestCheck, Context,
+                                  "performance-faster-string-find",
+                                  "performance-prefer-single-char-overloads");
+
+  EXPECT_THAT(
+      DiagConsumer.take(),
+      ElementsAre(
+          AllOf(ToolDiagMessage(
+                    "'performance-faster-string-find' check is deprecated and "
+                    "will be removed in a future release; consider using "
+                    "'performance-prefer-single-char-overloads' instead"),
+                ToolDiagLevel(Warning))));
+}
+
+TEST(CheckOptionsValidation,
+     DeprecatedAliasUtilsDisabledByWildcardAliasAndCanonicalCheck) {
+  ClangTidyOptions Options;
+  Options.Checks =
+      "performance-faster*,performance-prefer-single-char-overloads";
+
+  ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
+      ClangTidyGlobalOptions(), Options));
+  ClangTidyDiagnosticConsumer DiagConsumer(Context);
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(DiagnosticIDs::create(), *DiagOpts, &DiagConsumer,
+                       false);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
+
+  TestCheck TestCheck(&Context);
+  utils::diagDeprecatedCheckAlias(TestCheck, Context,
+                                  "performance-faster-string-find",
+                                  "performance-prefer-single-char-overloads");
+
+  EXPECT_TRUE(DiagConsumer.take().empty());
+}
+
+TEST(CheckOptionsValidation, DeprecatedAliasUtilsDisabledByWildcard) {
+  ClangTidyOptions Options;
+  Options.Checks = "performance-*";
+
+  ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
+      ClangTidyGlobalOptions(), Options));
+  ClangTidyDiagnosticConsumer DiagConsumer(Context);
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(DiagnosticIDs::create(), *DiagOpts, &DiagConsumer,
+                       false);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
+
+  TestCheck TestCheck(&Context);
+  utils::diagDeprecatedCheckAlias(TestCheck, Context,
+                                  "performance-faster-string-find",
+                                  "performance-prefer-single-char-overloads");
+
+  EXPECT_TRUE(DiagConsumer.take().empty());
+}
+
 TEST(CheckOptionsValidation, ValidIntOptions) {
   ClangTidyOptions Options;
   auto &CheckOptions = Options.CheckOptions;



More information about the llvm-branch-commits mailing list