https://github.com/localspook created https://github.com/llvm/llvm-project/pull/175477
Fixes #175475. This PR depends on #175473 (this is a sort of ad-hoc stack) >From c4d3a3cce72b8c3d2245fffcb5de691561cc4ffe Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <[email protected]> Date: Sun, 11 Jan 2026 16:55:44 -0800 Subject: [PATCH 1/2] [clang-tidy] Fix false positive from `readability-redundant-typename` on partially specialized variables --- .../readability/RedundantTypenameCheck.cpp | 27 ++++++++++--------- .../readability/redundant-typename.cpp | 10 +++++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp index 0816625b1937d..fde7748df31fa 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp @@ -25,22 +25,25 @@ void RedundantTypenameCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus20) return; - const auto InImplicitTypenameContext = anyOf( - hasParent(decl(anyOf( - typedefNameDecl(), templateTypeParmDecl(), nonTypeTemplateParmDecl(), - friendDecl(), fieldDecl(), - varDecl(hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())), - unless(parmVarDecl())), - parmVarDecl(hasParent(expr(requiresExpr()))), - parmVarDecl(hasParent(typeLoc(hasParent(decl( - anyOf(cxxMethodDecl(), hasParent(friendDecl()), + const auto InImplicitTypenameContext = + anyOf(hasParent(decl(anyOf( + typedefNameDecl(), templateTypeParmDecl(), + nonTypeTemplateParmDecl(), friendDecl(), fieldDecl(), + parmVarDecl(hasParent(expr(requiresExpr()))), + parmVarDecl(hasParent(typeLoc(hasParent(decl(anyOf( + cxxMethodDecl(), hasParent(friendDecl()), functionDecl(has(nestedNameSpecifier())), cxxDeductionGuideDecl(hasDeclContext(recordDecl())))))))), - // Match return types. - functionDecl(unless(cxxConversionDecl()))))), - hasParent(expr(anyOf(cxxNamedCastExpr(), cxxNewExpr())))); + // Match return types. + functionDecl(unless(cxxConversionDecl()))))), + hasParent(expr(anyOf(cxxNamedCastExpr(), cxxNewExpr())))); Finder->addMatcher( typeLoc(InImplicitTypenameContext).bind("dependentTypeLoc"), this); + Finder->addMatcher( + varDecl(hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())), + unless(parmVarDecl()), + hasTypeLoc(typeLoc().bind("dependentTypeLoc"))), + this); } void RedundantTypenameCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp index 96bd7b6412724..cb58826efbdaa 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp @@ -157,6 +157,16 @@ typename T::R v = typename T::R(); // CHECK-MESSAGES-20: :[[@LINE-1]]:1: warning: redundant 'typename' [readability-redundant-typename] // CHECK-FIXES-20: T::R v = typename T::R(); +template <typename T, typename> +typename T::R PartiallySpecializedVariable = true; +// CHECK-MESSAGES-20: :[[@LINE-1]]:1: warning: redundant 'typename' [readability-redundant-typename] +// CHECK-FIXES-20: T::R PartiallySpecializedVariable = true; + +template <typename T> +typename T::R PartiallySpecializedVariable<T, typename T::R> = false; +// CHECK-MESSAGES-20: :[[@LINE-1]]:1: warning: redundant 'typename' [readability-redundant-typename] +// CHECK-FIXES-20: T::R PartiallySpecializedVariable<T, typename T::R> = false; + #endif // __cplusplus >= 201402L template <typename T> >From 4eabdef606799e712c012df0a238e88e107ac843 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <[email protected]> Date: Sun, 11 Jan 2026 18:15:36 -0800 Subject: [PATCH 2/2] [clang-tidy] Fix false negatives around static data members in `readability-redundant-typename` --- .../readability/RedundantTypenameCheck.cpp | 3 +- .../readability/redundant-typename.cpp | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp index fde7748df31fa..676dc9c7a1582 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp @@ -40,7 +40,8 @@ void RedundantTypenameCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( typeLoc(InImplicitTypenameContext).bind("dependentTypeLoc"), this); Finder->addMatcher( - varDecl(hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())), + varDecl(hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl(), + cxxRecordDecl())), unless(parmVarDecl()), hasTypeLoc(typeLoc().bind("dependentTypeLoc"))), this); diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp index cb58826efbdaa..138e616774355 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp @@ -218,6 +218,10 @@ class A { // CHECK-MESSAGES-20: :[[@LINE-1]]:3: warning: redundant 'typename' [readability-redundant-typename] // CHECK-FIXES-20: T::R v; + static typename T::R StaticDataMember; + // CHECK-MESSAGES-20: :[[@LINE-1]]:10: warning: redundant 'typename' [readability-redundant-typename] + // CHECK-FIXES-20: static T::R StaticDataMember; + typename T::R // CHECK-MESSAGES-20: :[[@LINE-1]]:3: warning: redundant 'typename' [readability-redundant-typename] // CHECK-FIXES-20: T::R @@ -317,3 +321,29 @@ typename ClassWithNestedStruct<T>::Nested ClassWithNestedStruct<T>::g() { // CHECK-FIXES-20: ClassWithNestedStruct<T>::Nested ClassWithNestedStruct<T>::g() { return {}; } + +#if __cplusplus >= 201402L + +struct Foo { + template <typename T, typename> + static typename T::R PartiallySpecializedDataMember; + // CHECK-MESSAGES-20: :[[@LINE-1]]:10: warning: redundant 'typename' [readability-redundant-typename] + // CHECK-FIXES-20: static T::R PartiallySpecializedDataMember; + + template <typename T> + static typename T::R PartiallySpecializedDataMember<T, typename T::R> = false; + // CHECK-MESSAGES-20: :[[@LINE-1]]:10: warning: redundant 'typename' [readability-redundant-typename] + // CHECK-FIXES-20: static T::R PartiallySpecializedDataMember<T, typename T::R> = false; +}; + +template <typename T, typename> +typename T::R Foo::PartiallySpecializedDataMember = true; +// CHECK-MESSAGES-20: :[[@LINE-1]]:1: warning: redundant 'typename' [readability-redundant-typename] +// CHECK-FIXES-20: T::R Foo::PartiallySpecializedDataMember = true; + +template <typename T> +typename T::R Foo::PartiallySpecializedDataMember<T, typename T::V> = false; +// CHECK-MESSAGES-20: :[[@LINE-1]]:1: warning: redundant 'typename' [readability-redundant-typename] +// CHECK-FIXES-20: T::R Foo::PartiallySpecializedDataMember<T, typename T::V> = false; + +#endif // __cplusplus >= 201402L _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
