1 | // RUN: %check_clang_tidy %s abseil-str-cat-append %t |
2 | |
3 | typedef unsigned __INT16_TYPE__ char16; |
4 | typedef unsigned __INT32_TYPE__ char32; |
5 | typedef __SIZE_TYPE__ size; |
6 | |
7 | namespace std { |
8 | template <typename T> |
9 | class allocator {}; |
10 | template <typename T> |
11 | class char_traits {}; |
12 | template <typename C, typename T, typename A> |
13 | struct basic_string { |
14 | typedef basic_string<C, T, A> _Type; |
15 | basic_string(); |
16 | basic_string(const C* p, const A& a = A()); |
17 | |
18 | const C* c_str() const; |
19 | const C* data() const; |
20 | |
21 | _Type& append(const C* s); |
22 | _Type& append(const C* s, size n); |
23 | _Type& assign(const C* s); |
24 | _Type& assign(const C* s, size n); |
25 | |
26 | int compare(const _Type&) const; |
27 | int compare(const C* s) const; |
28 | int compare(size pos, size len, const _Type&) const; |
29 | int compare(size pos, size len, const C* s) const; |
30 | |
31 | size find(const _Type& str, size pos = 0) const; |
32 | size find(const C* s, size pos = 0) const; |
33 | size find(const C* s, size pos, size n) const; |
34 | |
35 | _Type& insert(size pos, const _Type& str); |
36 | _Type& insert(size pos, const C* s); |
37 | _Type& insert(size pos, const C* s, size n); |
38 | |
39 | _Type& operator+=(const _Type& str); |
40 | _Type& operator+=(const C* s); |
41 | _Type& operator=(const _Type& str); |
42 | _Type& operator=(const C* s); |
43 | }; |
44 | |
45 | typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string; |
46 | typedef basic_string<wchar_t, std::char_traits<wchar_t>, |
47 | std::allocator<wchar_t>> |
48 | wstring; |
49 | typedef basic_string<char16, std::char_traits<char16>, std::allocator<char16>> |
50 | u16string; |
51 | typedef basic_string<char32, std::char_traits<char32>, std::allocator<char32>> |
52 | u32string; |
53 | } // namespace std |
54 | |
55 | std::string operator+(const std::string&, const std::string&); |
56 | std::string operator+(const std::string&, const char*); |
57 | std::string operator+(const char*, const std::string&); |
58 | |
59 | bool operator==(const std::string&, const std::string&); |
60 | bool operator==(const std::string&, const char*); |
61 | bool operator==(const char*, const std::string&); |
62 | |
63 | namespace llvm { |
64 | struct StringRef { |
65 | StringRef(const char* p); |
66 | StringRef(const std::string&); |
67 | }; |
68 | } // namespace llvm |
69 | |
70 | namespace absl { |
71 | |
72 | struct AlphaNum { |
73 | AlphaNum(int i); |
74 | AlphaNum(double f); |
75 | AlphaNum(const char* c_str); |
76 | AlphaNum(const std::string& str); |
77 | |
78 | private: |
79 | AlphaNum(const AlphaNum&); |
80 | AlphaNum& operator=(const AlphaNum&); |
81 | }; |
82 | |
83 | std::string StrCat(const AlphaNum& A); |
84 | std::string StrCat(const AlphaNum& A, const AlphaNum& B); |
85 | |
86 | template <typename A> |
87 | void Foo(A& a) { |
88 | a = StrCat(a); |
89 | } |
90 | |
91 | void Bar() { |
92 | std::string A, B; |
93 | Foo<std::string>(a&: A); |
94 | |
95 | std::string C = StrCat(A); |
96 | A = StrCat(A); |
97 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: call to 'absl::StrCat' has no effect |
98 | A = StrCat(A, B); |
99 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty |
100 | // CHECK-FIXES: {{^}} absl::StrAppend(&A, B); |
101 | B = StrCat(A, B); |
102 | |
103 | #define M(X) X = StrCat(X, A) |
104 | M(B); |
105 | // CHECK-MESSAGES: [[@LINE-1]]:5: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty |
106 | // CHECK-FIXES: #define M(X) X = StrCat(X, A) |
107 | } |
108 | |
109 | void Regression_SelfAppend() { |
110 | std::string A; |
111 | A = StrCat(A, B: A); |
112 | } |
113 | |
114 | } // namespace absl |
115 | |
116 | void OutsideAbsl() { |
117 | std::string A, B; |
118 | A = absl::StrCat(A, B); |
119 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty |
120 | // CHECK-FIXES: {{^}} absl::StrAppend(&A, B); |
121 | } |
122 | |
123 | void OutsideUsingAbsl() { |
124 | std::string A, B; |
125 | using absl::StrCat; |
126 | A = StrCat(A, B); |
127 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: call 'absl::StrAppend' instead of 'absl::StrCat' when appending to a string to avoid a performance penalty |
128 | // CHECK-FIXES: {{^}} absl::StrAppend(&A, B); |
129 | } |
130 | |