Author: Daniil Dudkin Date: 2026-05-09T12:16:36+03:00 New Revision: d3a4bb081f6c3d6b410af0639f7ad2bb652c1d03
URL: https://github.com/llvm/llvm-project/commit/d3a4bb081f6c3d6b410af0639f7ad2bb652c1d03 DIFF: https://github.com/llvm/llvm-project/commit/d3a4bb081f6c3d6b410af0639f7ad2bb652c1d03.diff LOG: [clang-tidy] Avoid `use-nodiscard` false positives for class templates (#196661) Do not suggest adding `[[nodiscard]]` to functions returning a class template specialization whose primary template is already marked `[[nodiscard]]`. Class template specializations do not carry the `[[nodiscard]]` attribute on their own declarations, so `modernize-use-nodiscard` previously missed this case and emitted redundant diagnostics for return types such as: ```cpp template <class T> struct [[nodiscard]] Result; Result<int> f() const; ``` Fixes #163425. Added: Modified: clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/checkers/modernize/use-nodiscard.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp index 4940b5590f803..caa3d8c00681e 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp @@ -84,6 +84,9 @@ void UseNodiscardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) { auto FunctionObj = cxxRecordDecl(hasAnyName("::std::function", "::boost::function")); + auto NoDiscardClassTemplateSpecialization = + classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl( + has(cxxRecordDecl(hasAttr(attr::WarnUnusedResult)))))); // Find all non-void const methods which have not already been marked to // warn on unused result. @@ -93,6 +96,8 @@ void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) { unless(anyOf( returns(voidType()), returns(hasDeclaration(decl(hasAttr(attr::WarnUnusedResult)))), + returns(hasUnqualifiedDesugaredType(recordType( + hasDeclaration(NoDiscardClassTemplateSpecialization)))), isNoReturn(), isOverloadedOperator(), isVariadic(), hasTemplateReturnType(), hasClassMutableFields(), isConversionOperator(), hasAttr(attr::WarnUnusedResult), diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index c464be5f6311a..783c919f8ce8e 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -440,6 +440,11 @@ Changes in existing checks private deleted functions, if they do not have a public overload or are a special member function. +- Improved :doc:`modernize-use-nodiscard + <clang-tidy/checks/modernize/use-nodiscard>` check by avoiding false + positives on functions returning specializations of class templates marked + ``[[nodiscard]]``. + - Improved :doc:`modernize-use-std-format <clang-tidy/checks/modernize/use-std-format>` check: diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nodiscard.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nodiscard.cpp index 73ea4e46f76b6..e9097a7b19fdd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nodiscard.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nodiscard.cpp @@ -24,6 +24,12 @@ typedef const unsigned &my_unsigned_const_reference; struct NO_DISCARD NoDiscardStruct{}; +template <typename T> +struct NO_DISCARD NoDiscardTemplate {}; + +using NoDiscardTemplateAlias = NoDiscardTemplate<int>; +typedef NoDiscardTemplate<int> NoDiscardTemplateTypedef; + class Foo { public: using size_type = unsigned; @@ -164,6 +170,20 @@ class Foo { // Do not add ``[[nodiscard]]`` to functions returning types marked [[nodiscard]]. NoDiscardStruct f50() const; + + // Do not add ``[[nodiscard]]`` to functions returning class template + // specializations whose primary template is marked [[nodiscard]]. + NoDiscardTemplate<int> f51() const; + + NoDiscardTemplateAlias f52() const; + + NoDiscardTemplateTypedef f53() const; + + const NoDiscardTemplate<int> f54() const; + + const NoDiscardTemplate<int> &f55() const; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f55' should be marked NO_DISCARD [modernize-use-nodiscard] + // CHECK-FIXES: NO_DISCARD const NoDiscardTemplate<int> &f55() const; }; // Do not add ``[[nodiscard]]`` to Lambda. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
