[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.
This commit is contained in:
parent
7c9f1d2128
commit
d3a4bb081f
3 changed files with 30 additions and 0 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ public:
|
|||
|
||||
// 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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue