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>
Foo(A & a)87 void Foo(A& a) {
88 a = StrCat(a);
89 }
90
Bar()91 void Bar() {
92 std::string A, B;
93 Foo<std::string>(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
Regression_SelfAppend()109 void Regression_SelfAppend() {
110 std::string A;
111 A = StrCat(A, A);
112 }
113
114 } // namespace absl
115
OutsideAbsl()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
OutsideUsingAbsl()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