[clang-tools-extra] [clang-tidy] Add redundant qualified alias check (PR #180404)
Daniil Dudkin via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 14 04:38:08 PST 2026
https://github.com/unterumarmung updated https://github.com/llvm/llvm-project/pull/180404
>From 4f449c728d6b8b298f001a868428a8ae847158fb Mon Sep 17 00:00:00 2001
From: Daniil Dudkin <unterumarmung at yandex.ru>
Date: Sun, 8 Feb 2026 14:16:43 +0300
Subject: [PATCH 1/5] [clang-tidy] Add redundant qualified alias check
Introduce `readability-redundant-qualified-alias` to flag identity type aliases
that repeat a qualified name and suggest using-declarations when safe. The
check is conservative: it skips macros, elaborated keywords, dependent types,
and templates, and it suppresses fix-its when comments appear between the
alias name and '='. `OnlyNamespaceScope` controls whether local/class scopes
are included (default false).
---
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../readability/ReadabilityTidyModule.cpp | 3 +
.../RedundantQualifiedAliasCheck.cpp | 256 ++++++++++++++++++
.../RedundantQualifiedAliasCheck.h | 37 +++
clang-tools-extra/docs/ReleaseNotes.rst | 6 +
.../docs/clang-tidy/checks/list.rst | 1 +
.../readability/redundant-qualified-alias.rst | 29 ++
.../readability/redundant-qualified-alias.cpp | 122 +++++++++
8 files changed, 455 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index f1f3cde32feff..686e7c19d650b 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -47,6 +47,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
RedundantMemberInitCheck.cpp
RedundantParenthesesCheck.cpp
RedundantPreprocessorCheck.cpp
+ RedundantQualifiedAliasCheck.cpp
RedundantSmartptrGetCheck.cpp
RedundantStringCStrCheck.cpp
RedundantStringInitCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index c582dc98eac6b..8e9e00b23c84a 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -49,6 +49,7 @@
#include "RedundantMemberInitCheck.h"
#include "RedundantParenthesesCheck.h"
#include "RedundantPreprocessorCheck.h"
+#include "RedundantQualifiedAliasCheck.h"
#include "RedundantSmartptrGetCheck.h"
#include "RedundantStringCStrCheck.h"
#include "RedundantStringInitCheck.h"
@@ -148,6 +149,8 @@ class ReadabilityModule : public ClangTidyModule {
"readability-redundant-parentheses");
CheckFactories.registerCheck<RedundantPreprocessorCheck>(
"readability-redundant-preprocessor");
+ CheckFactories.registerCheck<RedundantQualifiedAliasCheck>(
+ "readability-redundant-qualified-alias");
CheckFactories.registerCheck<RedundantTypenameCheck>(
"readability-redundant-typename");
CheckFactories.registerCheck<ReferenceToConstructedTemporaryCheck>(
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
new file mode 100644
index 0000000000000..c6f59cf0e0306
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
@@ -0,0 +1,256 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RedundantQualifiedAliasCheck.h"
+#include "../utils/LexerUtils.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include <optional>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+struct NominalTypeLocInfo {
+ TypeLoc Loc;
+ bool HasQualifier = false;
+};
+
+struct EqualTokenInfo {
+ SourceLocation AfterEqualLoc;
+ bool SawComment = false;
+};
+
+} // namespace
+
+static bool isInNamespaceOrTU(const Decl *D) {
+ const DeclContext *DC = D->getDeclContext();
+ return DC && (DC->isTranslationUnit() || isa<NamespaceDecl>(DC));
+}
+
+static bool isAliasTemplate(const TypeAliasDecl *Alias) {
+ return Alias->getDescribedAliasTemplate() != nullptr;
+}
+
+static bool hasMacroInRange(SourceRange Range, const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ if (Range.isInvalid())
+ return true;
+ return utils::lexer::rangeContainsExpansionsOrDirectives(Range, SM, LangOpts);
+}
+
+static std::optional<NominalTypeLocInfo> peelToNominalTypeLoc(TypeLoc TL) {
+ while (!TL.isNull()) {
+ if (const auto ParenTL = TL.getAs<ParenTypeLoc>()) {
+ TL = ParenTL.getInnerLoc();
+ continue;
+ }
+ if (const auto AttrTL = TL.getAs<AttributedTypeLoc>()) {
+ // Preserve any attributes by rewriting only the alias name and '='.
+ TL = AttrTL.getModifiedLoc();
+ continue;
+ }
+
+ if (const auto TypedefTL = TL.getAs<TypedefTypeLoc>()) {
+ // Avoid rewriting aliases that use an elaborated keyword
+ // (class/struct/enum).
+ if (TypedefTL.getElaboratedKeywordLoc().isValid())
+ return std::nullopt;
+ const bool HasQualifier = static_cast<bool>(
+ TypedefTL.getQualifierLoc().getNestedNameSpecifier());
+ return NominalTypeLocInfo{TypedefTL, HasQualifier};
+ }
+
+ if (const auto TagTL = TL.getAs<TagTypeLoc>()) {
+ // Avoid rewriting aliases that use an elaborated keyword
+ // (class/struct/enum).
+ if (TagTL.getElaboratedKeywordLoc().isValid())
+ return std::nullopt;
+ const bool HasQualifier =
+ static_cast<bool>(TagTL.getQualifierLoc().getNestedNameSpecifier());
+ return NominalTypeLocInfo{TagTL, HasQualifier};
+ }
+
+ return std::nullopt;
+ }
+ return std::nullopt;
+}
+
+static const NamedDecl *getNamedDeclFromNominalTypeLoc(TypeLoc TL) {
+ if (const auto TypedefTL = TL.getAs<TypedefTypeLoc>())
+ return TypedefTL.getTypePtr()->getDecl();
+ if (const auto TagTL = TL.getAs<TagTypeLoc>())
+ return TagTL.getDecl();
+ return nullptr;
+}
+
+static bool hasSameUnqualifiedName(const TypeAliasDecl *Alias,
+ const NamedDecl *Target) {
+ return Alias->getName() == Target->getName();
+}
+
+static std::optional<EqualTokenInfo>
+findEqualTokenAfter(SourceLocation StartLoc, SourceLocation LimitLoc,
+ const SourceManager &SM, const LangOptions &LangOpts) {
+ if (StartLoc.isInvalid() || LimitLoc.isInvalid())
+ return std::nullopt;
+ if (StartLoc.isMacroID() || LimitLoc.isMacroID())
+ return std::nullopt;
+ if (!SM.isBeforeInTranslationUnit(StartLoc, LimitLoc))
+ return std::nullopt;
+
+ const SourceLocation SpellingStart = SM.getSpellingLoc(StartLoc);
+ const SourceLocation SpellingLimit = SM.getSpellingLoc(LimitLoc);
+ const FileID File = SM.getFileID(SpellingStart);
+ if (File != SM.getFileID(SpellingLimit))
+ return std::nullopt;
+
+ const StringRef Buf = SM.getBufferData(File);
+ const char *StartChar = SM.getCharacterData(SpellingStart);
+ Lexer Lex(SpellingStart, LangOpts, StartChar, StartChar, Buf.end());
+ Lex.SetCommentRetentionState(true);
+
+ Token Tok;
+ bool SawComment = false;
+ do {
+ Lex.LexFromRawLexer(Tok);
+ if (Tok.is(tok::comment))
+ SawComment = true;
+ if (Tok.is(tok::equal)) {
+ Token NextTok;
+ Lex.LexFromRawLexer(NextTok);
+ // Return the location *after* '=' so removal is token-preserving.
+ return EqualTokenInfo{NextTok.getLocation(), SawComment};
+ }
+ } while (Tok.isNot(tok::eof) && Tok.getLocation() < SpellingLimit);
+
+ return std::nullopt;
+}
+
+static std::optional<FixItHint> buildRemovalFixItAfterEqual(
+ const TypeAliasDecl *Alias, SourceLocation AfterEqualLoc,
+ const SourceManager &SM, const LangOptions &LangOpts) {
+ SourceLocation AliasLoc = Alias->getLocation();
+ if (AliasLoc.isInvalid() || AfterEqualLoc.isInvalid())
+ return std::nullopt;
+ if (AliasLoc.isMacroID() || AfterEqualLoc.isMacroID())
+ return std::nullopt;
+
+ AliasLoc = Lexer::GetBeginningOfToken(AliasLoc, SM, LangOpts);
+ if (AliasLoc.isInvalid())
+ return std::nullopt;
+
+ const CharSourceRange RemovalRange = Lexer::makeFileCharRange(
+ CharSourceRange::getCharRange(AliasLoc, AfterEqualLoc), SM, LangOpts);
+ if (RemovalRange.isInvalid())
+ return std::nullopt;
+
+ if (hasMacroInRange(RemovalRange.getAsRange(), SM, LangOpts))
+ // Avoid rewriting tokens that come from macro expansions.
+ return std::nullopt;
+
+ return FixItHint::CreateRemoval(RemovalRange);
+}
+
+RedundantQualifiedAliasCheck::RedundantQualifiedAliasCheck(
+ StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ OnlyNamespaceScope(Options.get("OnlyNamespaceScope", false)) {}
+
+void RedundantQualifiedAliasCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "OnlyNamespaceScope", OnlyNamespaceScope);
+}
+
+void RedundantQualifiedAliasCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(typeAliasDecl().bind("alias"), this);
+}
+
+void RedundantQualifiedAliasCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Alias = Result.Nodes.getNodeAs<TypeAliasDecl>("alias");
+ if (!Alias)
+ return;
+
+ if (OnlyNamespaceScope && !isInNamespaceOrTU(Alias))
+ return;
+
+ if (isAliasTemplate(Alias))
+ return;
+
+ if (Alias->getLocation().isInvalid() || Alias->getLocation().isMacroID())
+ return;
+
+ const TypeSourceInfo *TSI = Alias->getTypeSourceInfo();
+ if (!TSI)
+ return;
+
+ const TypeLoc WrittenTL = TSI->getTypeLoc();
+ if (WrittenTL.isNull())
+ return;
+
+ if (WrittenTL.getType()->isDependentType())
+ return;
+
+ const SourceManager &SM = *Result.SourceManager;
+ const LangOptions &LangOpts = getLangOpts();
+ if (hasMacroInRange(WrittenTL.getSourceRange(), SM, LangOpts))
+ return;
+
+ const std::optional<NominalTypeLocInfo> NominalInfo =
+ peelToNominalTypeLoc(WrittenTL);
+ if (!NominalInfo)
+ return;
+
+ if (!NominalInfo->HasQualifier)
+ // Unqualified RHS would not gain anything from a using-declaration.
+ return;
+
+ const TypeLoc NominalTL = NominalInfo->Loc;
+ const NamedDecl *Target = getNamedDeclFromNominalTypeLoc(NominalTL);
+ if (!Target)
+ return;
+
+ if (!hasSameUnqualifiedName(Alias, Target))
+ return;
+
+ const SourceLocation AliasLoc = Alias->getLocation();
+ const SourceLocation RhsBeginLoc = WrittenTL.getBeginLoc();
+ const CharSourceRange AliasToRhsRange = Lexer::makeFileCharRange(
+ CharSourceRange::getCharRange(AliasLoc, RhsBeginLoc), SM, LangOpts);
+ if (AliasToRhsRange.isInvalid())
+ return;
+ if (hasMacroInRange(AliasToRhsRange.getAsRange(), SM, LangOpts))
+ return;
+
+ std::optional<EqualTokenInfo> EqualInfo =
+ findEqualTokenAfter(AliasLoc, RhsBeginLoc, SM, LangOpts);
+ if (!EqualInfo || EqualInfo->AfterEqualLoc.isInvalid())
+ return;
+
+ auto Diag = diag(Alias->getLocation(),
+ "type alias is redundant; use a using-declaration instead");
+
+ if (EqualInfo->SawComment) {
+ // Suppress fix-it: avoid deleting comments between alias name and '='.
+ return;
+ }
+
+ if (const std::optional<FixItHint> Fix = buildRemovalFixItAfterEqual(
+ Alias, EqualInfo->AfterEqualLoc, SM, LangOpts)) {
+ Diag << *Fix;
+ }
+}
+
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h
new file mode 100644
index 0000000000000..201ce73f3594a
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTQUALIFIEDALIASCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTQUALIFIEDALIASCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+
+/// Finds identity type aliases to qualified names that can be expressed as
+/// using-declarations.
+///
+/// For the user-facing documentation see:
+/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-qualified-alias.html
+class RedundantQualifiedAliasCheck : public ClangTidyCheck {
+public:
+ RedundantQualifiedAliasCheck(StringRef Name, ClangTidyContext *Context);
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus11; // C++11 or later.
+ }
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ const bool OnlyNamespaceScope;
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTQUALIFIEDALIASCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 5c0060877a67f..9d99fb972606c 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -133,6 +133,12 @@ New checks
Finds and removes redundant conversions from ``std::[w|u8|u16|u32]string_view`` to
``std::[...]string`` in call expressions expecting ``std::[...]string_view``.
+- New :doc:`readability-redundant-qualified-alias
+ <clang-tidy/checks/readability/redundant-qualified-alias>` check.
+
+ Finds redundant identity type aliases of the form ``using X = ns::X;`` and
+ suggests rewriting them as using-declarations when safe.
+
- New :doc:`readability-trailing-comma
<clang-tidy/checks/readability/trailing-comma>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 0eabd9929dc39..75bc868cf0066 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -414,6 +414,7 @@ Clang-Tidy Checks
:doc:`readability-redundant-member-init <readability/redundant-member-init>`, "Yes"
:doc:`readability-redundant-parentheses <readability/redundant-parentheses>`, "Yes"
:doc:`readability-redundant-preprocessor <readability/redundant-preprocessor>`,
+ :doc:`readability-redundant-qualified-alias <readability/redundant-qualified-alias>`, "Yes"
:doc:`readability-redundant-smartptr-get <readability/redundant-smartptr-get>`, "Yes"
:doc:`readability-redundant-string-cstr <readability/redundant-string-cstr>`, "Yes"
:doc:`readability-redundant-string-init <readability/redundant-string-init>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
new file mode 100644
index 0000000000000..37b2551c70a3d
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
@@ -0,0 +1,29 @@
+.. title:: clang-tidy - readability-redundant-qualified-alias
+
+readability-redundant-qualified-alias
+=====================================
+
+Finds redundant identity type aliases that simply re-expose a qualified name
+and can be replaced with a using-declaration.
+
+.. code-block:: c++
+
+ using CommentToken = clang::tidy::utils::lexer::CommentToken;
+
+ // becomes
+
+ using clang::tidy::utils::lexer::CommentToken;
+
+The check is conservative and only warns when the alias name exactly matches
+the unqualified name of a non-dependent, non-specialized named type written
+with a qualifier. It skips alias templates, dependent forms, elaborated
+keywords (``class``, ``struct``, ``enum``, ``typename``), and cases involving
+macros or comments between the alias name and ``=``.
+
+Options
+-------
+
+.. option:: OnlyNamespaceScope
+
+ When false (default), consider aliases declared in any scope. When true,
+ only consider aliases declared in a namespace or the translation unit.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
new file mode 100644
index 0000000000000..ef5f391934eb2
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
@@ -0,0 +1,122 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s readability-redundant-qualified-alias %t
+// RUN: %check_clang_tidy -check-suffix=NS -std=c++11-or-later %s readability-redundant-qualified-alias %t -- \
+// RUN: -config='{CheckOptions: { readability-redundant-qualified-alias.OnlyNamespaceScope: true }}'
+
+namespace n1 {
+struct Foo {};
+struct Bar {};
+struct Attr {};
+struct Commented {};
+struct Elab {};
+struct MacroEq {};
+struct MacroType {};
+struct PtrType {};
+struct LocalType {};
+} // namespace n1
+
+namespace n2 {
+namespace n3 {
+struct Deep {};
+} // namespace n3
+} // namespace n2
+
+namespace td {
+typedef n1::Foo TypedefFoo;
+} // namespace td
+
+struct GlobalType {};
+
+using Foo = n1::Foo;
+// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-FIXES: using n1::Foo;
+
+using Bar = ::n1::Bar;
+// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-FIXES: using ::n1::Bar;
+
+using Attr = n1::Attr __attribute__((aligned(8)));
+// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-FIXES: using n1::Attr __attribute__((aligned(8)));
+
+using Deep = n2::n3::Deep;
+// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-FIXES: using n2::n3::Deep;
+
+using TypedefFoo = td::TypedefFoo;
+// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-FIXES: using td::TypedefFoo;
+
+using GlobalType = ::GlobalType;
+// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-FIXES: using ::GlobalType;
+
+using Builtin = int;
+// CHECK-FIXES: using Builtin = int;
+
+using PtrType = n1::PtrType *;
+// CHECK-FIXES: using PtrType = n1::PtrType *;
+
+namespace templ {
+template <typename T>
+struct Vec {};
+} // namespace templ
+
+using Vec = templ::Vec<int>;
+// CHECK-FIXES: using Vec = templ::Vec<int>;
+
+namespace templ_alias {
+template <typename T>
+using Foo = n1::Foo;
+} // namespace templ_alias
+
+template <typename T>
+struct Dependent {
+ using X = typename T::X;
+};
+
+using Elab = class n1::Elab;
+// CHECK-FIXES: using Elab = class n1::Elab;
+
+using Commented /*comment*/ = n1::Commented;
+// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-FIXES: using Commented /*comment*/ = n1::Commented;
+
+#define ALIAS MacroType
+using ALIAS = n1::MacroType;
+// CHECK-FIXES: #define ALIAS MacroType
+// CHECK-FIXES: using ALIAS = n1::MacroType;
+
+#define RHS n1::MacroType
+using MacroType = RHS;
+// CHECK-FIXES: #define RHS n1::MacroType
+// CHECK-FIXES: using MacroType = RHS;
+
+#define EQ =
+using MacroEq EQ n1::MacroEq;
+// CHECK-FIXES: #define EQ =
+// CHECK-FIXES: using MacroEq EQ n1::MacroEq;
+
+struct Base {
+ using T = n1::Foo;
+};
+
+struct Derived : Base {
+ using T = Base::T;
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+ // CHECK-FIXES: using Base::T;
+ // CHECK-FIXES-NS: using T = Base::T;
+};
+
+void local_scope() {
+ using LocalType = n1::LocalType;
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+ // CHECK-FIXES: using n1::LocalType;
+ // CHECK-FIXES-NS: using LocalType = n1::LocalType;
+}
>From eba18f6c72a93e450453bc8f6ae23693467e7689 Mon Sep 17 00:00:00 2001
From: Daniil Dudkin <unterumarmung at yandex.ru>
Date: Sun, 8 Feb 2026 17:52:11 +0300
Subject: [PATCH 2/5] Fix review comments
---
.../readability/redundant-qualified-alias.cpp | 63 +++++++++++--------
1 file changed, 36 insertions(+), 27 deletions(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
index ef5f391934eb2..32931c7d6191b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
@@ -27,40 +27,42 @@ typedef n1::Foo TypedefFoo;
struct GlobalType {};
using Foo = n1::Foo;
-// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
-// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-FIXES: using n1::Foo;
using Bar = ::n1::Bar;
-// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
-// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-FIXES: using ::n1::Bar;
using Attr = n1::Attr __attribute__((aligned(8)));
-// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
-// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-FIXES: using n1::Attr __attribute__((aligned(8)));
using Deep = n2::n3::Deep;
-// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
-// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-FIXES: using n2::n3::Deep;
using TypedefFoo = td::TypedefFoo;
-// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
-// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-FIXES: using td::TypedefFoo;
using GlobalType = ::GlobalType;
-// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
-// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-FIXES: using ::GlobalType;
using Builtin = int;
-// CHECK-FIXES: using Builtin = int;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
using PtrType = n1::PtrType *;
-// CHECK-FIXES: using PtrType = n1::PtrType *;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
namespace templ {
template <typename T>
@@ -68,40 +70,45 @@ struct Vec {};
} // namespace templ
using Vec = templ::Vec<int>;
-// CHECK-FIXES: using Vec = templ::Vec<int>;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
namespace templ_alias {
template <typename T>
using Foo = n1::Foo;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
} // namespace templ_alias
template <typename T>
struct Dependent {
using X = typename T::X;
+ // CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
};
using Elab = class n1::Elab;
-// CHECK-FIXES: using Elab = class n1::Elab;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
using Commented /*comment*/ = n1::Commented;
-// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
-// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-FIXES: using Commented /*comment*/ = n1::Commented;
-
#define ALIAS MacroType
using ALIAS = n1::MacroType;
-// CHECK-FIXES: #define ALIAS MacroType
-// CHECK-FIXES: using ALIAS = n1::MacroType;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
#define RHS n1::MacroType
using MacroType = RHS;
-// CHECK-FIXES: #define RHS n1::MacroType
-// CHECK-FIXES: using MacroType = RHS;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
#define EQ =
using MacroEq EQ n1::MacroEq;
-// CHECK-FIXES: #define EQ =
-// CHECK-FIXES: using MacroEq EQ n1::MacroEq;
+// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
struct Base {
using T = n1::Foo;
@@ -109,14 +116,16 @@ struct Base {
struct Derived : Base {
using T = Base::T;
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+ // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
// CHECK-FIXES: using Base::T;
// CHECK-FIXES-NS: using T = Base::T;
};
void local_scope() {
using LocalType = n1::LocalType;
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
+ // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
// CHECK-FIXES: using n1::LocalType;
// CHECK-FIXES-NS: using LocalType = n1::LocalType;
}
>From 9cc26307480f8b5953c4172c9b217e729c6da986 Mon Sep 17 00:00:00 2001
From: Daniil Dudkin <unterumarmung at yandex.ru>
Date: Sun, 8 Feb 2026 18:59:11 +0300
Subject: [PATCH 3/5] fix docs
---
clang-tools-extra/docs/ReleaseNotes.rst | 4 ++--
.../checks/readability/redundant-qualified-alias.rst | 9 +++++----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 9d99fb972606c..fff0b16c85d45 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -136,8 +136,8 @@ New checks
- New :doc:`readability-redundant-qualified-alias
<clang-tidy/checks/readability/redundant-qualified-alias>` check.
- Finds redundant identity type aliases of the form ``using X = ns::X;`` and
- suggests rewriting them as using-declarations when safe.
+ Finds redundant identity type aliases that re-expose a qualified name and can
+ be replaced with a ``using`` declaration.
- New :doc:`readability-trailing-comma
<clang-tidy/checks/readability/trailing-comma>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
index 37b2551c70a3d..d75c71ed76af5 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
@@ -3,8 +3,8 @@
readability-redundant-qualified-alias
=====================================
-Finds redundant identity type aliases that simply re-expose a qualified name
-and can be replaced with a using-declaration.
+Finds redundant identity type aliases that re-expose a qualified name and can
+be replaced with a ``using`` declaration.
.. code-block:: c++
@@ -25,5 +25,6 @@ Options
.. option:: OnlyNamespaceScope
- When false (default), consider aliases declared in any scope. When true,
- only consider aliases declared in a namespace or the translation unit.
+ When ``true``, only consider aliases declared in a namespace or the
+ translation unit. When ``false``, also consider aliases declared inside
+ classes, functions, and lambdas. Default is ``false``.
>From dac7d39e158de5fb19fbfd7a6dda0f46f5d90a5f Mon Sep 17 00:00:00 2001
From: Daniil Dudkin <unterumarmung at yandex.ru>
Date: Wed, 11 Feb 2026 23:35:04 +0300
Subject: [PATCH 4/5] add ast matchers
---
.../RedundantQualifiedAliasCheck.cpp | 46 ++++++++++++-------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
index c6f59cf0e0306..496158669226b 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
@@ -34,15 +34,6 @@ struct EqualTokenInfo {
} // namespace
-static bool isInNamespaceOrTU(const Decl *D) {
- const DeclContext *DC = D->getDeclContext();
- return DC && (DC->isTranslationUnit() || isa<NamespaceDecl>(DC));
-}
-
-static bool isAliasTemplate(const TypeAliasDecl *Alias) {
- return Alias->getDescribedAliasTemplate() != nullptr;
-}
-
static bool hasMacroInRange(SourceRange Range, const SourceManager &SM,
const LangOptions &LangOpts) {
if (Range.isInvalid())
@@ -87,6 +78,19 @@ static std::optional<NominalTypeLocInfo> peelToNominalTypeLoc(TypeLoc TL) {
return std::nullopt;
}
+namespace {
+
+AST_MATCHER(TypeAliasDecl, isAliasTemplate) {
+ return Node.getDescribedAliasTemplate() != nullptr;
+}
+
+AST_MATCHER(TypeLoc, hasQualifiedNominalTypeLoc) {
+ std::optional<NominalTypeLocInfo> Result = peelToNominalTypeLoc(Node);
+ return Result && Result->HasQualifier;
+}
+
+} // namespace
+
static const NamedDecl *getNamedDeclFromNominalTypeLoc(TypeLoc TL) {
if (const auto TypedefTL = TL.getAs<TypedefTypeLoc>())
return TypedefTL.getTypePtr()->getDecl();
@@ -174,7 +178,23 @@ void RedundantQualifiedAliasCheck::storeOptions(
}
void RedundantQualifiedAliasCheck::registerMatchers(MatchFinder *Finder) {
- Finder->addMatcher(typeAliasDecl().bind("alias"), this);
+ if (OnlyNamespaceScope) {
+ Finder->addMatcher(
+ typeAliasDecl(
+ unless(isAliasTemplate()), unless(isImplicit()),
+ unless(isExpansionInSystemHeader()),
+ hasTypeLoc(hasQualifiedNominalTypeLoc()),
+ hasDeclContext(anyOf(translationUnitDecl(), namespaceDecl())))
+ .bind("alias"),
+ this);
+ return;
+ }
+ Finder->addMatcher(typeAliasDecl(unless(isAliasTemplate()),
+ unless(isImplicit()),
+ unless(isExpansionInSystemHeader()),
+ hasTypeLoc(hasQualifiedNominalTypeLoc()))
+ .bind("alias"),
+ this);
}
void RedundantQualifiedAliasCheck::check(
@@ -183,12 +203,6 @@ void RedundantQualifiedAliasCheck::check(
if (!Alias)
return;
- if (OnlyNamespaceScope && !isInNamespaceOrTU(Alias))
- return;
-
- if (isAliasTemplate(Alias))
- return;
-
if (Alias->getLocation().isInvalid() || Alias->getLocation().isMacroID())
return;
>From 927472ab681f2db7a51945d1f945365b4ba33ee6 Mon Sep 17 00:00:00 2001
From: Daniil Dudkin <unterumarmung at yandex.ru>
Date: Sat, 14 Feb 2026 15:35:04 +0300
Subject: [PATCH 5/5] address review comment
---
.../RedundantQualifiedAliasCheck.cpp | 40 +++++++++++++++----
.../readability/redundant-qualified-alias.cpp | 34 +++++++++++++++-
2 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
index 496158669226b..04ffe77cf1126 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
@@ -8,12 +8,17 @@
#include "RedundantQualifiedAliasCheck.h"
#include "../utils/LexerUtils.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
#include "clang/AST/TypeLoc.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include <cassert>
#include <optional>
using namespace clang::ast_matchers;
@@ -43,10 +48,6 @@ static bool hasMacroInRange(SourceRange Range, const SourceManager &SM,
static std::optional<NominalTypeLocInfo> peelToNominalTypeLoc(TypeLoc TL) {
while (!TL.isNull()) {
- if (const auto ParenTL = TL.getAs<ParenTypeLoc>()) {
- TL = ParenTL.getInnerLoc();
- continue;
- }
if (const auto AttrTL = TL.getAs<AttributedTypeLoc>()) {
// Preserve any attributes by rewriting only the alias name and '='.
TL = AttrTL.getModifiedLoc();
@@ -104,6 +105,28 @@ static bool hasSameUnqualifiedName(const TypeAliasDecl *Alias,
return Alias->getName() == Target->getName();
}
+static bool isControlFlowInitParent(const DeclStmt *DeclS,
+ const DynTypedNode &Parent) {
+ return llvm::TypeSwitch<const Stmt *, bool>(Parent.get<Stmt>())
+ .Case<IfStmt, SwitchStmt, ForStmt, CXXForRangeStmt>(
+ [&](const auto *S) { return S->getInit() == DeclS; })
+ .Default(false);
+}
+
+static bool isInControlFlowInitStatement(const TypeAliasDecl *Alias,
+ ASTContext &Context) {
+ for (const DynTypedNode &AliasParent : Context.getParents(*Alias)) {
+ const auto *DeclS = AliasParent.get<DeclStmt>();
+ if (!DeclS)
+ continue;
+
+ for (const DynTypedNode &DeclSParent : Context.getParents(*DeclS))
+ if (isControlFlowInitParent(DeclS, DeclSParent))
+ return true;
+ }
+ return false;
+}
+
static std::optional<EqualTokenInfo>
findEqualTokenAfter(SourceLocation StartLoc, SourceLocation LimitLoc,
const SourceManager &SM, const LangOptions &LangOpts) {
@@ -182,7 +205,6 @@ void RedundantQualifiedAliasCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
typeAliasDecl(
unless(isAliasTemplate()), unless(isImplicit()),
- unless(isExpansionInSystemHeader()),
hasTypeLoc(hasQualifiedNominalTypeLoc()),
hasDeclContext(anyOf(translationUnitDecl(), namespaceDecl())))
.bind("alias"),
@@ -191,7 +213,6 @@ void RedundantQualifiedAliasCheck::registerMatchers(MatchFinder *Finder) {
}
Finder->addMatcher(typeAliasDecl(unless(isAliasTemplate()),
unless(isImplicit()),
- unless(isExpansionInSystemHeader()),
hasTypeLoc(hasQualifiedNominalTypeLoc()))
.bind("alias"),
this);
@@ -200,12 +221,15 @@ void RedundantQualifiedAliasCheck::registerMatchers(MatchFinder *Finder) {
void RedundantQualifiedAliasCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *Alias = Result.Nodes.getNodeAs<TypeAliasDecl>("alias");
- if (!Alias)
- return;
+ assert(Alias && "matcher must bind alias");
if (Alias->getLocation().isInvalid() || Alias->getLocation().isMacroID())
return;
+ assert(Result.Context && "match result should always carry ASTContext");
+ if (isInControlFlowInitStatement(Alias, *Result.Context))
+ return;
+
const TypeSourceInfo *TSI = Alias->getTypeSourceInfo();
if (!TSI)
return;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
index 32931c7d6191b..197b8d9677767 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
@@ -1,6 +1,9 @@
// RUN: %check_clang_tidy -std=c++11-or-later %s readability-redundant-qualified-alias %t
// RUN: %check_clang_tidy -check-suffix=NS -std=c++11-or-later %s readability-redundant-qualified-alias %t -- \
// RUN: -config='{CheckOptions: { readability-redundant-qualified-alias.OnlyNamespaceScope: true }}'
+// RUN: %check_clang_tidy -check-suffixes=,CXX23 -std=c++23 %s readability-redundant-qualified-alias %t
+// RUN: %check_clang_tidy -check-suffixes=NS,NS-CXX23 -std=c++23 %s readability-redundant-qualified-alias %t -- \
+// RUN: -config='{CheckOptions: { readability-redundant-qualified-alias.OnlyNamespaceScope: true }}'
namespace n1 {
struct Foo {};
@@ -119,7 +122,6 @@ struct Derived : Base {
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
// CHECK-FIXES: using Base::T;
- // CHECK-FIXES-NS: using T = Base::T;
};
void local_scope() {
@@ -127,5 +129,33 @@ void local_scope() {
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias]
// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
// CHECK-FIXES: using n1::LocalType;
- // CHECK-FIXES-NS: using LocalType = n1::LocalType;
}
+
+#if __cplusplus >= 202302L
+void cxx23_init_statement_scope(bool Cond) {
+ if (using Foo = n1::Foo; Cond) {
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+
+ switch (using Bar = ::n1::Bar; 0) {
+ default:
+ break;
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+
+ for (using Deep = n2::n3::Deep; Cond;) {
+ Cond = false;
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+
+ int Values[] = {0};
+ for (using GlobalType = ::GlobalType; int V : Values) {
+ (void)V;
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+}
+#endif
More information about the cfe-commits
mailing list