From 42bc3275d3687524ddc0d20c72722b9324f87be4 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Mon, 17 Jan 2022 20:50:32 +0100 Subject: [PATCH] [clang-tidy] Fix `readability-redundant-declaration` false positive for template friend declaration Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=48086 | PR#48086 ]]. The problem is that the current matcher uses `hasParent()` to detect friend declarations, but for a template friend declaration, the immediate parent of the `FunctionDecl` is a `FunctionTemplateDecl`, not the `FriendDecl`. Therefore, I have replaced the matcher with `hasAncestor()`. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D114299 --- .../readability/RedundantDeclarationCheck.cpp | 2 +- .../checkers/readability-redundant-declaration.cpp | 26 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp index dfe3fbc..78ba969 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp @@ -37,7 +37,7 @@ void RedundantDeclarationCheck::registerMatchers(MatchFinder *Finder) { functionDecl(unless(anyOf( isDefinition(), isDefaulted(), doesDeclarationForceExternallyVisibleDefinition(), - hasParent(friendDecl())))))) + hasAncestor(friendDecl())))))) .bind("Decl"), this); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp index 90fb98a..85ee9a5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp @@ -70,6 +70,32 @@ struct Friendly { void enemy(); +template +struct TemplateFriendly { + template + friend void generic_friend(); +}; + +template +void generic_friend() {} + +TemplateFriendly template_friendly; + +template +struct TemplateFriendly2 { + template + friend void generic_friend2() {} +}; + +template +void generic_friend2(); + +void generic_friend_caller() { + TemplateFriendly2 f; + generic_friend2(); +} + + namespace macros { #define DECLARE(x) extern int x #define DEFINE(x) extern int x; int x = 42 -- 2.7.4