brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.3 KiB · c5d1f17 Raw
305 lines · cpp
1// RUN: %check_clang_tidy %s abseil-string-find-str-contains %t --2 3using size_t = decltype(sizeof(int));4 5namespace std {6 7// Lightweight standin for std::string.8template <typename C>9class basic_string {10public:11  basic_string();12  basic_string(const basic_string &);13  basic_string(const C *);14  ~basic_string();15  int find(basic_string s, int pos = 0);16  int find(const C *s, int pos = 0);17  int find(const C *s, int pos, int n);18  int find(char c, int pos = 0);19  static constexpr size_t npos = -1;20};21typedef basic_string<char> string;22 23// Lightweight standin for std::string_view.24template <typename C>25class basic_string_view {26public:27  basic_string_view();28  basic_string_view(const basic_string_view &);29  basic_string_view(const C *);30  ~basic_string_view();31  int find(basic_string_view s, int pos = 0);32  int find(const C *s, int pos = 0);33  int find(const C *s, int pos, int n);34  int find(char c, int pos = 0);35  static constexpr size_t npos = -1;36};37typedef basic_string_view<char> string_view;38 39} // namespace std40 41namespace absl {42 43// Lightweight standin for absl::string_view.44class string_view {45public:46  string_view();47  string_view(const string_view &);48  string_view(const char *);49  ~string_view();50  int find(string_view s, int pos = 0);51  int find(const char *s, int pos = 0);52  int find(const char *s, int pos, int n);53  int find(char c, int pos = 0);54  static constexpr size_t npos = -1;55};56 57} // namespace absl58 59// Functions that take and return our various string-like types.60std::string foo_ss(std::string);61std::string_view foo_ssv(std::string_view);62absl::string_view foo_asv(absl::string_view);63std::string bar_ss();64std::string_view bar_ssv();65absl::string_view bar_asv();66 67// Confirms that find==npos and find!=npos work for each supported type, when68// npos comes from the correct type.69void basic_tests() {70  std::string ss;71  ss.find("a") == std::string::npos;72  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of find() == npos73  // CHECK-FIXES: !absl::StrContains(ss, "a");74 75  ss.find("a") != std::string::npos;76  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of find() != npos77  // CHECK-FIXES: absl::StrContains(ss, "a");78 79  std::string::npos != ss.find("a");80  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of81  // CHECK-FIXES: absl::StrContains(ss, "a");82 83  std::string_view ssv;84  ssv.find("a") == std::string_view::npos;85  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of86  // CHECK-FIXES: !absl::StrContains(ssv, "a");87 88  ssv.find("a") != std::string_view::npos;89  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of90  // CHECK-FIXES: absl::StrContains(ssv, "a");91 92  std::string_view::npos != ssv.find("a");93  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of94  // CHECK-FIXES: absl::StrContains(ssv, "a");95 96  absl::string_view asv;97  asv.find("a") == absl::string_view::npos;98  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of99  // CHECK-FIXES: !absl::StrContains(asv, "a");100 101  asv.find("a") != absl::string_view::npos;102  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of103  // CHECK-FIXES: absl::StrContains(asv, "a");104 105  absl::string_view::npos != asv.find("a");106  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of107  // CHECK-FIXES: absl::StrContains(asv, "a");108}109 110// Confirms that it works even if you mix-and-match the type for find and for111// npos.  (One of the reasons for this checker is to clean up cases that112// accidentally mix-and-match like this.  absl::StrContains is less113// error-prone.)114void mismatched_npos() {115  std::string ss;116  ss.find("a") == std::string_view::npos;117  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of118  // CHECK-FIXES: !absl::StrContains(ss, "a");119 120  ss.find("a") != absl::string_view::npos;121  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of122  // CHECK-FIXES: absl::StrContains(ss, "a");123 124  std::string_view ssv;125  ssv.find("a") == absl::string_view::npos;126  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of127  // CHECK-FIXES: !absl::StrContains(ssv, "a");128 129  ssv.find("a") != std::string::npos;130  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of131  // CHECK-FIXES: absl::StrContains(ssv, "a");132 133  absl::string_view asv;134  asv.find("a") == std::string::npos;135  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of136  // CHECK-FIXES: !absl::StrContains(asv, "a");137 138  asv.find("a") != std::string_view::npos;139  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of140  // CHECK-FIXES: absl::StrContains(asv, "a");141}142 143// Confirms that it works even when the needle or the haystack are more144// complicated expressions.145void subexpression_tests() {146  std::string ss, ss2;147  foo_ss(ss).find(ss2) == std::string::npos;148  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of149  // CHECK-FIXES: !absl::StrContains(foo_ss(ss), ss2);150 151  ss.find(foo_ss(ss2)) != std::string::npos;152  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of153  // CHECK-FIXES: absl::StrContains(ss, foo_ss(ss2));154 155  foo_ss(bar_ss()).find(foo_ss(ss2)) != std::string::npos;156  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of157  // CHECK-FIXES: absl::StrContains(foo_ss(bar_ss()), foo_ss(ss2));158 159  std::string_view ssv, ssv2;160  foo_ssv(ssv).find(ssv2) == std::string_view::npos;161  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of162  // CHECK-FIXES: !absl::StrContains(foo_ssv(ssv), ssv2);163 164  ssv.find(foo_ssv(ssv2)) != std::string_view::npos;165  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of166  // CHECK-FIXES: absl::StrContains(ssv, foo_ssv(ssv2));167 168  foo_ssv(bar_ssv()).find(foo_ssv(ssv2)) != std::string_view::npos;169  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of170  // CHECK-FIXES: absl::StrContains(foo_ssv(bar_ssv()), foo_ssv(ssv2));171 172  absl::string_view asv, asv2;173  foo_asv(asv).find(asv2) == absl::string_view::npos;174  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of175  // CHECK-FIXES: !absl::StrContains(foo_asv(asv), asv2);176 177  asv.find(foo_asv(asv2)) != absl::string_view::npos;178  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of179  // CHECK-FIXES: absl::StrContains(asv, foo_asv(asv2));180 181  foo_asv(bar_asv()).find(foo_asv(asv2)) != absl::string_view::npos;182  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StrContains instead of183  // CHECK-FIXES: absl::StrContains(foo_asv(bar_asv()), foo_asv(asv2));184}185 186// Confirms that it works with string literal, char* and const char* parameters.187void string_literal_and_char_ptr_tests() {188  char *c = nullptr;189  const char *cc = nullptr;190 191  std::string ss;192  ss.find("c") == std::string::npos;193  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of194  // CHECK-FIXES: !absl::StrContains(ss, "c");195 196  ss.find(c) == std::string::npos;197  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of198  // CHECK-FIXES: !absl::StrContains(ss, c);199 200  ss.find(cc) == std::string::npos;201  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of202  // CHECK-FIXES: !absl::StrContains(ss, cc);203 204  std::string_view ssv;205  ssv.find("c") == std::string_view::npos;206  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of207  // CHECK-FIXES: !absl::StrContains(ssv, "c");208 209  ssv.find(c) == std::string_view::npos;210  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of211  // CHECK-FIXES: !absl::StrContains(ssv, c);212 213  ssv.find(cc) == std::string_view::npos;214  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of215  // CHECK-FIXES: !absl::StrContains(ssv, cc);216 217  absl::string_view asv;218  asv.find("c") == absl::string_view::npos;219  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of220  // CHECK-FIXES: !absl::StrContains(asv, "c");221 222  asv.find(c) == absl::string_view::npos;223  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of224  // CHECK-FIXES: !absl::StrContains(asv, c);225 226  asv.find(cc) == absl::string_view::npos;227  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of228  // CHECK-FIXES: !absl::StrContains(asv, cc);229}230 231void char_param_tests() {232  std::string ss;233  ss.find('c') == std::string::npos;234  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of235  // CHECK-FIXES: !absl::StrContains(ss, 'c');236 237  std::string_view ssv;238  ssv.find('c') == std::string_view::npos;239  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of240  // CHECK-FIXES: !absl::StrContains(ssv, 'c');241 242  absl::string_view asv;243  asv.find('c') == absl::string_view::npos;244  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of245  // CHECK-FIXES: !absl::StrContains(asv, 'c');246}247 248#define FOO(a, b, c, d) ((a).find(b) == std::string::npos ? (c) : (d))249 250// Confirms that it does not match when a macro would be "torn" by the fix.251void no_tearing_macros() {252  std::string h = "helo";253  FOO(h, "x", 5, 6);254}255 256// Confirms that it does not match when the pos parameter is non-zero.257void no_nonzero_pos() {258  std::string ss;259  ss.find("a", 1) == std::string::npos;260 261  std::string_view ssv;262  ssv.find("a", 2) == std::string_view::npos;263 264  absl::string_view asv;265  asv.find("a", 3) == std::string_view::npos;266}267 268// Confirms that it does not match when the count parameter is present.269void no_count() {270  std::string ss;271  ss.find("a", 0, 1) == std::string::npos;272 273  std::string_view ssv;274  ssv.find("a", 0, 1) == std::string_view::npos;275 276  absl::string_view asv;277  asv.find("a", 0, 1) == std::string_view::npos;278}279 280// Confirms that it does not match when it's compared to something other than281// npos, even if the value is the same as npos.282void no_non_npos() {283  std::string ss;284  ss.find("a") == 0;285  ss.find("a") == 1;286  ss.find("a") == -1;287 288  std::string_view ssv;289  ssv.find("a") == 0;290  ssv.find("a") == 1;291  ssv.find("a") == -1;292 293  absl::string_view asv;294  asv.find("a") == 0;295  asv.find("a") == 1;296  asv.find("a") == -1;297}298 299// Confirms that it does not match if the two operands are the same.300void no_symmetric_operands() {301  std::string ss;302  ss.find("a") == ss.find("a");303  std::string::npos == std::string::npos;304}305