brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · 88d0483 Raw
375 lines · cpp
1// RUN: %check_clang_tidy -std=c++20 %s modernize-use-starts-ends-with %t -- \2// RUN:   -- -isystem %clang_tidy_headers3 4#include <string.h>5#include <string>6 7std::string foo(std::string);8std::string bar();9 10class sub_string : public std::string {};11class sub_sub_string : public sub_string {};12 13struct string_like {14  bool starts_with(const char *s) const;15  size_t find(const char *s, size_t pos = 0) const;16};17 18struct string_like_camel {19  bool startsWith(const char *s) const;20  size_t find(const char *s, size_t pos = 0) const;21};22 23struct prefer_underscore_version {24  bool starts_with(const char *s) const;25  bool startsWith(const char *s) const;26  size_t find(const char *s, size_t pos = 0) const;27};28 29struct prefer_underscore_version_flip {30  bool startsWith(const char *s) const;31  bool starts_with(const char *s) const;32  size_t find(const char *s, size_t pos = 0) const;33};34 35void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,36          string_like sl, string_like_camel slc, prefer_underscore_version puv,37          prefer_underscore_version_flip puvf) {38  s.find("a") == 0;39  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of find [modernize-use-starts-ends-with]40  // CHECK-FIXES: s.starts_with("a");41 42  (((((s)).find("a")))) == ((0));43  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with44  // CHECK-FIXES: ((s)).starts_with("a");45 46  (s + "a").find("a") == ((0));47  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with48  // CHECK-FIXES: (s + "a").starts_with("a");49 50  s.find(s) == 0;51  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with52  // CHECK-FIXES: s.starts_with(s);53 54  s.find("aaa") != 0;55  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with56  // CHECK-FIXES: !s.starts_with("aaa");57 58  s.find(foo(foo(bar()))) != 0;59  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with60  // CHECK-FIXES: !s.starts_with(foo(foo(bar())));61 62  if (s.find("....") == 0) { /* do something */ }63  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with64  // CHECK-FIXES: if (s.starts_with("....")) { /* do something */ }65 66  0 != s.find("a");67  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with68  // CHECK-FIXES: !s.starts_with("a");69 70  s.rfind("a", 0) == 0;71  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of rfind [modernize-use-starts-ends-with]72  // CHECK-FIXES: s.starts_with("a");73 74  s.rfind(s, 0) == 0;75  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with76  // CHECK-FIXES: s.starts_with(s);77 78  s.rfind("aaa", 0) != 0;79  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with80  // CHECK-FIXES: !s.starts_with("aaa");81 82  s.rfind(foo(foo(bar())), 0) != 0;83  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with84  // CHECK-FIXES: !s.starts_with(foo(foo(bar())));85 86  if (s.rfind("....", 0) == 0) { /* do something */ }87  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with88  // CHECK-FIXES: if (s.starts_with("....")) { /* do something */ }89 90  0 != s.rfind("a", 0);91  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with92  // CHECK-FIXES: !s.starts_with("a");93 94  #define FIND find95  s.FIND("a") == 0;96  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with97  // CHECK-FIXES: s.starts_with("a");98 99  #define PREFIX "a"100  s.find(PREFIX) == 0;101  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with102  // CHECK-FIXES: s.starts_with(PREFIX);103 104  #define ZERO 0105  s.find("a") == ZERO;106  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with107  // CHECK-FIXES: s.starts_with("a");108 109  sv.find("a") == 0;110  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with111  // CHECK-FIXES: sv.starts_with("a");112 113  sv.rfind("a", 0) != 0;114  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with115  // CHECK-FIXES: !sv.starts_with("a");116 117  ss.find("a") == 0;118  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with119  // CHECK-FIXES: ss.starts_with("a");120 121  sss.find("a") == 0;122  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with123  // CHECK-FIXES: sss.starts_with("a");124 125  sl.find("a") == 0;126  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with127  // CHECK-FIXES: sl.starts_with("a");128 129  slc.find("a") == 0;130  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use startsWith131  // CHECK-FIXES: slc.startsWith("a");132 133  puv.find("a") == 0;134  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with135  // CHECK-FIXES: puv.starts_with("a");136 137  puvf.find("a") == 0;138  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with139  // CHECK-FIXES: puvf.starts_with("a");140 141  s.compare(0, 1, "a") == 0;142  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare [modernize-use-starts-ends-with]143  // CHECK-FIXES: s.starts_with("a");144 145  s.compare(0, 1, "a") != 0;146  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare [modernize-use-starts-ends-with]147  // CHECK-FIXES: !s.starts_with("a");148 149  s.compare(0, strlen("a"), "a") == 0;150  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with151  // CHECK-FIXES: s.starts_with("a");152 153  s.compare(0, std::strlen("a"), "a") == 0;154  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with155  // CHECK-FIXES: s.starts_with("a");156 157  s.compare(0, std::strlen(("a")), "a") == 0;158  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with159  // CHECK-FIXES: s.starts_with("a");160 161  s.compare(0, std::strlen(("a")), (("a"))) == 0;162  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with163  // CHECK-FIXES: s.starts_with("a");164 165  s.compare(0, s.size(), s) == 0;166  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with167  // CHECK-FIXES: s.starts_with(s);168 169  s.compare(0, s.length(), s) == 0;170  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with171  // CHECK-FIXES: s.starts_with(s);172 173  0 != s.compare(0, sv.length(), sv);174  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with175  // CHECK-FIXES: !s.starts_with(sv);176 177  #define LENGTH(x) (x).length()178  s.compare(0, LENGTH(s), s) == 0;179  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with180  // CHECK-FIXES: s.starts_with(s);181 182  s.compare(ZERO, LENGTH(s), s) == ZERO;183  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with184  // CHECK-FIXES: s.starts_with(s);185 186  s.compare(ZERO, LENGTH(sv), sv) != 0;187  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with188  // CHECK-FIXES: !s.starts_with(sv);189 190  s.compare(s.size() - 6, 6, "suffix") == 0;191  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with192  // CHECK-FIXES: s.ends_with("suffix");193 194  s.compare(s.size() - 6, strlen("abcdef"), "suffix") == 0;195  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with196  // CHECK-FIXES: s.ends_with("suffix");197 198  std::string suffix = "suffix";199  s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0;200  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with201  // CHECK-FIXES: s.ends_with(suffix);202 203  s.rfind("suffix") == s.size() - 6;204  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with205  // CHECK-FIXES: s.ends_with("suffix");206 207  s.rfind("suffix") == s.size() - strlen("suffix");208  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with209  // CHECK-FIXES: s.ends_with("suffix");210 211  s.rfind(suffix) == s.size() - suffix.size();212  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with213  // CHECK-FIXES: s.ends_with(suffix);214 215  s.rfind(suffix, std::string::npos) == s.size() - suffix.size();216  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with217  // CHECK-FIXES: s.ends_with(suffix);218 219  s.rfind(suffix) == (s.size() - suffix.size());220  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with221  // CHECK-FIXES: s.ends_with(suffix);222 223  s.rfind(suffix, s.npos) == (s.size() - suffix.size());224  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with225  // CHECK-FIXES: s.ends_with(suffix);226 227  s.rfind(suffix, s.npos) == (((s.size()) - (suffix.size())));228  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with229  // CHECK-FIXES: s.ends_with(suffix);230 231  s.rfind(suffix) != s.size() - suffix.size();232  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with233  // CHECK-FIXES: !s.ends_with(suffix);234 235  (s.size() - suffix.size()) == s.rfind(suffix);236  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with237  // CHECK-FIXES: s.ends_with(suffix);238 239  s.find("a", 0) == 0;240  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with241  // CHECK-FIXES: s.starts_with("a");242 243  s.find(s, ZERO) == 0;244  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with245  // CHECK-FIXES: s.starts_with(s);246 247  s.find(s, 0) == ZERO;248  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with249  // CHECK-FIXES: s.starts_with(s);250 251  s.find("aaa", 0, 3) == 0;252  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with253  // CHECK-FIXES: s.starts_with("aaa");254 255  s.find("aaa", ZERO, 3) == 0;256  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with257  // CHECK-FIXES: s.starts_with("aaa");258 259  s.find("aaa", ZERO, strlen(("aaa"))) == ZERO;260  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with261  // CHECK-FIXES: s.starts_with("aaa");262 263  s.rfind("aaa", 0, 3) != 0;264  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with265  // CHECK-FIXES: !s.starts_with("aaa");266 267  s.rfind("aaa", ZERO, 3) != 0;268  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with269  // CHECK-FIXES: !s.starts_with("aaa");270 271  s.rfind("aaa", ZERO, strlen(("aaa"))) == ZERO;272  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with273  // CHECK-FIXES: s.starts_with("aaa");274 275  struct S {276    std::string s;277  } t;278  t.s.rfind(suffix) == (t.s.size() - suffix.size());279  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with280  // CHECK-FIXES: t.s.ends_with(suffix);281 282  // Expressions that don't trigger the check are here.283  #define EQ(x, y) ((x) == (y))284  EQ(s.find("a"), 0);285 286  #define DOTFIND(x, y) (x).find(y)287  DOTFIND(s, "a") == 0;288 289  #define STARTS_WITH_COMPARE(x, y) (x).compare(0, (x).size(), (y))290  STARTS_WITH_COMPARE(s, s) == 0;291 292  s.compare(0, 1, "ab") == 0;293  s.rfind(suffix, 1) == s.size() - suffix.size();294 295  #define STR(x) std::string(x)296  0 == STR(s).find("a");297 298  #define STRING s299  if (0 == STRING.find("ala")) { /* do something */}300 301  // Cases when literal-size and size parameters are different are not being matched.302  s.find("aaa", 0, 2) == 0;303  s.find("aaa", 0, strlen("aa")) == 0;304  s.rfind("aaa", 0, 2) == 0;305  s.rfind("aaa", 0, strlen("aa")) == 0;306}307 308void test_substr() {309    std::string str("hello world");310    std::string prefix = "hello";311    312    // Basic pattern313    str.substr(0, 5) == "hello";314    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]315    // CHECK-FIXES: str.starts_with("hello");316    317    // With string literal on left side318    "hello" == str.substr(0, 5);319    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]320    // CHECK-FIXES: str.starts_with("hello");321    322    // Inequality comparison323    str.substr(0, 5) != "world";324    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]325    // CHECK-FIXES: !str.starts_with("world");326    327    // Ensure non-zero start position is not transformed328    str.substr(1, 5) == "hello";329    str.substr(0, 4) == "hello"; // Length mismatch330    331    size_t len = 5;332    str.substr(0, len) == "hello"; // Non-constant length333 334    // String literal with size calculation335    str.substr(0, strlen("hello")) == "hello";336    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]337    // CHECK-FIXES: str.starts_with("hello");338 339    str.substr(0, prefix.size()) == prefix;340    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]341    // CHECK-FIXES: str.starts_with(prefix);342 343    str.substr(0, prefix.length()) == prefix;344    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]345    // CHECK-FIXES: str.starts_with(prefix);346 347    // Tests to verify macro behavior348    #define MSG "hello"349    str.substr(0, strlen(MSG)) == MSG;350    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]351    // CHECK-FIXES: str.starts_with(MSG);352 353    #define STARTS_WITH(X, Y) (X).substr(0, (Y).size()) == (Y)354    STARTS_WITH(str, prefix);355 356    #define SUBSTR(X, A, B) (X).substr((A), (B))357    SUBSTR(str, 0, 6) == "prefix";358 359    #define STR() str360    SUBSTR(STR(), 0, 6) == "prefix";361    "prefix" == SUBSTR(STR(), 0, 6);362 363    str.substr(0, strlen("hello123")) == "hello";364}365 366void test_operator_rewriting(std::string str, std::string prefix) {367  str.substr(0, prefix.size()) == prefix;368  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr369  // CHECK-FIXES: str.starts_with(prefix);370 371  str.substr(0, prefix.size()) != prefix;372  // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr373  // CHECK-FIXES: !str.starts_with(prefix);374}375