================
@@ -0,0 +1,108 @@
+// RUN: %check_clang_tidy %s readability-stringview-substr %t
+
+namespace std {
+template <typename T>
+class basic_string_view {
+public:
+  using size_type = unsigned long;
+  static constexpr size_type npos = -1;
+
+  basic_string_view(const char*) {}
+  basic_string_view substr(size_type pos, size_type count = npos) const { 
return *this; }
+  void remove_prefix(size_type n) {}
+  void remove_suffix(size_type n) {}
+  size_type length() const { return 0; }
+  basic_string_view& operator=(const basic_string_view&) { return *this; }
+};
+
+using string_view = basic_string_view<char>;
+} // namespace std
+
+void test_basic() {
+  std::string_view sv("test");
+  std::string_view sv1("test");
+  std::string_view sv2("test");
+
+  // Should match: remove_prefix
+  sv = sv.substr(5);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_prefix' over 
'substr' for removing characters from the start [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_prefix(5)
+
+  // Should match: remove_suffix
+  sv = sv.substr(0, sv.length() - 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix(3)
+
+  // Should match: remove_suffix with complex expression
+  sv = sv.substr(0, sv.length() - (3 + 2));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix((3 + 2))
+}
+
+void test_copies() {
+  std::string_view sv("test");
+  std::string_view sv1("test");
+  std::string_view sv2("test");
+
+  // Should match: remove redundant self copies
+  sv = sv.substr(0, sv.length());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant self-copy 
[readability-stringview-substr]
+
+  sv = sv.substr(0, sv.length() - 0);
+    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant self-copy 
[readability-stringview-substr]
+
+  // Should match: simplify copies between different variables
+  sv1 = sv.substr(0, sv.length());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer direct copy over substr 
[readability-stringview-substr]
+  // CHECK-FIXES: sv1 = sv
+
+  sv2 = sv.substr(0, sv.length() - 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer direct copy over substr 
[readability-stringview-substr]
+  // CHECK-FIXES: sv2 = sv
+}
+
+void test_zero_forms() {
+  std::string_view sv("test");
+  const int kZero = 0;
+  constexpr std::string_view::size_type Zero = 0;
+  #define START_POS 0
+
+  // Should match: various forms of zero in first argument
+  sv = sv.substr(kZero, sv.length() - 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix(3)
+
+  sv = sv.substr(Zero, sv.length() - 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix(3)
+
+  sv = sv.substr(START_POS, sv.length() - 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix(3)
+
+  sv = sv.substr((0), sv.length() - 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix(3)
+
+  sv = sv.substr(0u, sv.length() - 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix(3)
+
+  sv = sv.substr(0UL, sv.length() - 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer 'remove_suffix' over 
'substr' for removing characters from the end [readability-stringview-substr]
+  // CHECK-FIXES: sv.remove_suffix(3)
+}
+
+void test_should_not_match() {
+  std::string_view sv("test");
+  std::string_view sv1("test");
+  std::string_view sv2("test");
+
+  // No match: substr used for prefix or mid-view
+  sv = sv.substr(1, sv.length() - 3); // No warning
+
+  // No match: Different string_views
+  sv = sv2.substr(0, sv2.length() - 3); // No warning
----------------
denzor200 wrote:

Why no match? I don't see any trouble with
```
sv = sv2;
sv.remove_suffix(3);
```
Of couse still no match for const version of `sv`

https://github.com/llvm/llvm-project/pull/120055
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to