267 lines · cpp
1// RUN: %check_clang_tidy -std=c++17-or-later %s modernize-use-nodiscard %t -- \2// RUN: -config="{CheckOptions: {modernize-use-nodiscard.ReplacementString: 'NO_DISCARD'}}"3 4namespace std {5template <class>6class function;7class string {};8}9 10namespace boost {11template <class>12class function;13}14 15#define MUST_USE_RESULT __attribute__((warn_unused_result))16#define NO_DISCARD [[nodiscard]]17#define NO_RETURN [[noreturn]]18 19#define BOOLEAN_FUNC bool f23() const20 21typedef unsigned my_unsigned;22typedef unsigned &my_unsigned_reference;23typedef const unsigned &my_unsigned_const_reference;24 25struct NO_DISCARD NoDiscardStruct{};26 27class Foo {28public:29 using size_type = unsigned;30 31 bool f1() const;32 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked NO_DISCARD [modernize-use-nodiscard]33 // CHECK-FIXES: NO_DISCARD bool f1() const;34 35 bool f2(int) const;36 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked NO_DISCARD [modernize-use-nodiscard]37 // CHECK-FIXES: NO_DISCARD bool f2(int) const;38 39 bool f3(const int &) const;40 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked NO_DISCARD [modernize-use-nodiscard]41 // CHECK-FIXES: NO_DISCARD bool f3(const int &) const;42 43 bool f4(void) const;44 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked NO_DISCARD [modernize-use-nodiscard]45 // CHECK-FIXES: NO_DISCARD bool f4(void) const;46 47 // negative tests48 49 void f5() const;50 51 bool f6();52 53 bool f7(int &);54 55 bool f8(int &) const;56 57 bool f9(int *) const;58 59 bool f10(const int &, int &) const;60 61 NO_DISCARD bool f12() const;62 63 MUST_USE_RESULT bool f13() const;64 65 [[nodiscard]] bool f11() const;66 67 [[clang::warn_unused_result]] bool f11a() const;68 69 [[gnu::warn_unused_result]] bool f11b() const;70 71 bool _f20() const;72 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function '_f20' should be marked NO_DISCARD [modernize-use-nodiscard]73 // CHECK-FIXES: NO_DISCARD bool _f20() const;74 75 NO_RETURN bool f21() const;76 77 ~Foo();78 79 bool operator+=(int) const;80 81 // extra keywords (virtual,inline,const) on return type82 83 virtual bool f14() const;84 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f14' should be marked NO_DISCARD [modernize-use-nodiscard]85 // CHECK-FIXES: NO_DISCARD virtual bool f14() const;86 87 const bool f15() const;88 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f15' should be marked NO_DISCARD [modernize-use-nodiscard]89 // CHECK-FIXES: NO_DISCARD const bool f15() const;90 91 inline const bool f16() const;92 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f16' should be marked NO_DISCARD [modernize-use-nodiscard]93 // CHECK-FIXES: NO_DISCARD inline const bool f16() const;94 95 inline const std::string &f45() const;96 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f45' should be marked NO_DISCARD [modernize-use-nodiscard]97 // CHECK-FIXES: NO_DISCARD inline const std::string &f45() const;98 99 inline virtual const bool f17() const;100 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f17' should be marked NO_DISCARD [modernize-use-nodiscard]101 // CHECK-FIXES: NO_DISCARD inline virtual const bool f17() const;102 103 // inline with body104 bool f18() const 105 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f18' should be marked NO_DISCARD [modernize-use-nodiscard]106 // CHECK-FIXES: NO_DISCARD bool f18() const 107 {108 return true;109 }110 111 bool f19() const;112 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f19' should be marked NO_DISCARD [modernize-use-nodiscard]113 // CHECK-FIXES: NO_DISCARD bool f19() const;114 115 BOOLEAN_FUNC;116 117 bool f24(size_type) const;118 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f24' should be marked NO_DISCARD [modernize-use-nodiscard]119 // CHECK-FIXES: NO_DISCARD bool f24(size_type) const;120 121 bool f28(my_unsigned) const;122 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f28' should be marked NO_DISCARD [modernize-use-nodiscard]123 // CHECK-FIXES: NO_DISCARD bool f28(my_unsigned) const;124 125 bool f29(my_unsigned_reference) const;126 127 bool f30(my_unsigned_const_reference) const;128 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f30' should be marked NO_DISCARD [modernize-use-nodiscard]129 // CHECK-FIXES: NO_DISCARD bool f30(my_unsigned_const_reference) const;130 131 template <class F>132 F f37(F a, F b) const;133 134 template <class F>135 bool f38(F a) const;136 137 bool f39(const std::function<bool()> &predicate) const;138 139 bool f39a(std::function<bool()> predicate) const;140 141 bool f39b(const std::function<bool()> predicate) const;142 143 bool f45(const boost::function<bool()> &predicate) const;144 145 bool f45a(boost::function<bool()> predicate) const;146 147 bool f45b(const boost::function<bool()> predicate) const;148 149 // Do not add ``[[nodiscard]]`` to parameter packs.150 template <class... Args>151 bool ParameterPack(Args... args) const;152 153 template <typename... Targs>154 bool ParameterPack2(Targs... Fargs) const;155 156 // Do not add ``[[nodiscard]]`` to variadic functions.157 bool VariadicFunctionTest(const int &, ...) const;158 159 // Do not add ``[[nodiscard]]`` to non constant static functions.160 static bool not_empty();161 162 // Do not add ``[[nodiscard]]`` to conversion functions.163 // explicit operator bool() const { return true; }164 165 // Do not add ``[[nodiscard]]`` to functions returning types marked [[nodiscard]].166 NoDiscardStruct f50() const;167};168 169// Do not add ``[[nodiscard]]`` to Lambda.170const auto nonConstReferenceType = [] {171 return true;172};173 174auto lambda1 = [](int a, int b) { return a < b; };175auto lambda1a = [](int a) { return a; };176auto lambda1b = []() { return true;};177 178auto get_functor = [](bool check) {179 return [&](const std::string& sr)->std::string {180 if(check){181 return std::string();182 }183 return std::string();184 };185};186 187// Do not add ``[[nodiscard]]`` to function definition.188bool Foo::f19() const {189 return true;190}191 192template <class T>193class Bar {194public:195 using value_type = T;196 using reference = value_type &;197 using const_reference = const value_type &;198 199 // Do not add ``[[nodiscard]]`` to non explicit conversion functions.200 operator bool() const { return true; }201 202 bool empty() const;203 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'empty' should be marked NO_DISCARD [modernize-use-nodiscard]204 // CHECK-FIXES: NO_DISCARD bool empty() const;205 206 // we cannot assume that the template parameter isn't a pointer207 bool f25(value_type) const;208 209 bool f27(reference) const;210 211 typename T::value_type f35() const;212 213 T f34() const;214 215 bool f31(T) const;216 217 bool f33(T &) const;218 219 bool f26(const_reference) const;220 221 bool f32(const T &) const;222};223 224template <typename _Tp, int cn>225class Vec {226public:227 Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor228 229 Vec cross(const Vec &v) const;230 231 template <typename T2>232 operator Vec<T2, cn>() const;233};234 235template <class T>236class Bar2 {237public:238 typedef T value_type;239 typedef value_type &reference;240 typedef const value_type &const_reference;241 242 // we cannot assume that the template parameter isn't a pointer243 bool f40(value_type) const;244 245 bool f41(reference) const;246 247 value_type f42() const;248 249 typename T::value_type f43() const;250 251 bool f44(const_reference) const;252};253 254template <class T>255bool Bar<T>::empty() const {256 return true;257}258 259// don't mark typical ``[[nodiscard]]`` candidates if the class260// has mutable member variables261class MutableExample {262 mutable bool m_isempty;263 264public:265 bool empty() const;266};267