1 | // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.llvm.Conventions \ |
2 | // RUN: -std=c++14 -verify %s |
3 | |
4 | #include "Inputs/system-header-simulator-cxx.h" |
5 | |
6 | //===----------------------------------------------------------------------===// |
7 | // Forward declarations for StringRef tests. |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | using size_type = size_t; |
11 | |
12 | namespace std { |
13 | |
14 | template <class T> |
15 | struct numeric_limits { const static bool is_signed; }; |
16 | |
17 | } // end of namespace std |
18 | |
19 | namespace llvm { |
20 | |
21 | template <class T> |
22 | struct iterator_range; |
23 | |
24 | template <class Func> |
25 | struct function_ref; |
26 | |
27 | struct hash_code; |
28 | |
29 | template <class T> |
30 | struct SmallVectorImpl; |
31 | |
32 | struct APInt; |
33 | |
34 | class StringRef { |
35 | public: |
36 | static const size_t npos = ~size_t(0); |
37 | using iterator = const char *; |
38 | using const_iterator = const char *; |
39 | using size_type = size_t; |
40 | |
41 | /*implicit*/ StringRef() = default; |
42 | StringRef(std::nullptr_t) = delete; |
43 | /*implicit*/ StringRef(const char *Str); |
44 | /*implicit*/ constexpr StringRef(const char *data, size_t length); |
45 | /*implicit*/ StringRef(const std::string &Str); |
46 | |
47 | static StringRef withNullAsEmpty(const char *data); |
48 | iterator begin() const; |
49 | iterator end() const; |
50 | const unsigned char *bytes_begin() const; |
51 | const unsigned char *bytes_end() const; |
52 | iterator_range<const unsigned char *> bytes() const; |
53 | const char *data() const; |
54 | bool empty() const; |
55 | size_t size() const; |
56 | char front() const; |
57 | char back() const; |
58 | template <typename Allocator> |
59 | StringRef copy(Allocator &A) const; |
60 | bool equals(StringRef RHS) const; |
61 | bool equals_lower(StringRef RHS) const; |
62 | int compare(StringRef RHS) const; |
63 | int compare_lower(StringRef RHS) const; |
64 | int compare_numeric(StringRef RHS) const; |
65 | unsigned edit_distance(StringRef Other, bool AllowReplacements = true, |
66 | unsigned MaxEditDistance = 0) const; |
67 | std::string str() const; |
68 | char operator[](size_t Index) const; |
69 | template <typename T> |
70 | typename std::enable_if<std::is_same<T, std::string>::value, |
71 | StringRef>::type & |
72 | operator=(T &&Str) = delete; |
73 | operator std::string() const; |
74 | bool startswith(StringRef Prefix) const; |
75 | bool startswith_lower(StringRef Prefix) const; |
76 | bool endswith(StringRef Suffix) const; |
77 | bool endswith_lower(StringRef Suffix) const; |
78 | size_t find(char C, size_t From = 0) const; |
79 | size_t find_lower(char C, size_t From = 0) const; |
80 | size_t find_if(function_ref<bool(char)> F, size_t From = 0) const; |
81 | size_t find_if_not(function_ref<bool(char)> F, size_t From = 0) const; |
82 | size_t find(StringRef Str, size_t From = 0) const; |
83 | size_t find_lower(StringRef Str, size_t From = 0) const; |
84 | size_t rfind(char C, size_t From = npos) const; |
85 | size_t rfind_lower(char C, size_t From = npos) const; |
86 | size_t rfind(StringRef Str) const; |
87 | size_t rfind_lower(StringRef Str) const; |
88 | size_t find_first_of(char C, size_t From = 0) const; |
89 | size_t find_first_of(StringRef Chars, size_t From = 0) const; |
90 | size_t find_first_not_of(char C, size_t From = 0) const; |
91 | size_t find_first_not_of(StringRef Chars, size_t From = 0) const; |
92 | size_t find_last_of(char C, size_t From = npos) const; |
93 | size_t find_last_of(StringRef Chars, size_t From = npos) const; |
94 | size_t find_last_not_of(char C, size_t From = npos) const; |
95 | size_t find_last_not_of(StringRef Chars, size_t From = npos) const; |
96 | bool contains(StringRef Other) const; |
97 | bool contains(char C) const; |
98 | bool contains_lower(StringRef Other) const; |
99 | bool contains_lower(char C) const; |
100 | size_t count(char C) const; |
101 | size_t count(StringRef Str) const; |
102 | template <typename T> |
103 | typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type |
104 | getAsInteger(unsigned Radix, T &Result) const; |
105 | template <typename T> |
106 | typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type |
107 | getAsInteger(unsigned Radix, T &Result) const; |
108 | template <typename T> |
109 | typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type |
110 | consumeInteger(unsigned Radix, T &Result); |
111 | template <typename T> |
112 | typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type |
113 | consumeInteger(unsigned Radix, T &Result); |
114 | bool getAsInteger(unsigned Radix, APInt &Result) const; |
115 | bool getAsDouble(double &Result, bool AllowInexact = true) const; |
116 | std::string lower() const; |
117 | std::string upper() const; |
118 | StringRef substr(size_t Start, size_t N = npos) const; |
119 | StringRef take_front(size_t N = 1) const; |
120 | StringRef take_back(size_t N = 1) const; |
121 | StringRef take_while(function_ref<bool(char)> F) const; |
122 | StringRef take_until(function_ref<bool(char)> F) const; |
123 | StringRef drop_front(size_t N = 1) const; |
124 | StringRef drop_back(size_t N = 1) const; |
125 | StringRef drop_while(function_ref<bool(char)> F) const; |
126 | StringRef drop_until(function_ref<bool(char)> F) const; |
127 | bool consume_front(StringRef Prefix); |
128 | bool consume_back(StringRef Suffix); |
129 | StringRef slice(size_t Start, size_t End) const; |
130 | std::pair<StringRef, StringRef> split(char Separator) const; |
131 | std::pair<StringRef, StringRef> split(StringRef Separator) const; |
132 | std::pair<StringRef, StringRef> rsplit(StringRef Separator) const; |
133 | void split(SmallVectorImpl<StringRef> &A, |
134 | StringRef Separator, int MaxSplit = -1, |
135 | bool KeepEmpty = true) const; |
136 | void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1, |
137 | bool KeepEmpty = true) const; |
138 | std::pair<StringRef, StringRef> rsplit(char Separator) const; |
139 | StringRef ltrim(char Char) const; |
140 | StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const; |
141 | StringRef rtrim(char Char) const; |
142 | StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const; |
143 | StringRef trim(char Char) const; |
144 | StringRef trim(StringRef Chars = " \t\n\v\f\r") const; |
145 | }; |
146 | |
147 | inline bool operator==(StringRef LHS, StringRef RHS); |
148 | inline bool operator!=(StringRef LHS, StringRef RHS); |
149 | inline bool operator<(StringRef LHS, StringRef RHS); |
150 | inline bool operator<=(StringRef LHS, StringRef RHS); |
151 | inline bool operator>(StringRef LHS, StringRef RHS); |
152 | inline bool operator>=(StringRef LHS, StringRef RHS); |
153 | inline std::string &operator+=(std::string &buffer, StringRef string); |
154 | hash_code hash_value(StringRef S); |
155 | |
156 | } // end of namespace llvm |
157 | |
158 | //===----------------------------------------------------------------------===// |
159 | // Tests for StringRef. |
160 | //===----------------------------------------------------------------------===// |
161 | |
162 | void temporarayStringToStringRefAssignmentTest() { |
163 | // TODO: Emit a warning. |
164 | llvm::StringRef Ref = std::string("Yimmy yummy test."); |
165 | } |
166 | |
167 | void assigningStringToStringRefWithLongerLifetimeTest() { |
168 | llvm::StringRef Ref; |
169 | { |
170 | // TODO: Emit a warning. |
171 | std::string TmpStr("This is a fine string."); |
172 | Ref = TmpStr; |
173 | } |
174 | } |
175 | |
176 | std::string getTemporaryString() { |
177 | return "One two three."; |
178 | } |
179 | |
180 | void assigningTempStringFromFunctionToStringRefTest() { |
181 | // TODO: Emit a warning. |
182 | llvm::StringRef Ref = getTemporaryString(); |
183 | } |
184 | |
185 | //===----------------------------------------------------------------------===// |
186 | // Forward declaration for Clang AST nodes. |
187 | //===----------------------------------------------------------------------===// |
188 | |
189 | namespace llvm { |
190 | |
191 | template <class T, int Size> |
192 | struct SmallVector {}; |
193 | |
194 | } // end of namespace llvm |
195 | |
196 | namespace clang { |
197 | |
198 | struct Type; |
199 | struct Decl; |
200 | struct Stmt; |
201 | struct Attr; |
202 | |
203 | } // end of namespace clang |
204 | |
205 | //===----------------------------------------------------------------------===// |
206 | // Tests for Clang AST nodes. |
207 | //===----------------------------------------------------------------------===// |
208 | |
209 | namespace clang { |
210 | |
211 | struct Type { |
212 | std::string str; // expected-warning{{AST class 'Type' has a field 'str' that allocates heap memory (type std::string)}} |
213 | }; |
214 | |
215 | } // end of namespace clang |
216 | |
217 | namespace clang { |
218 | |
219 | struct Decl { |
220 | llvm::SmallVector<int, 5> Vec; // expected-warning{{AST class 'Decl' has a field 'Vec' that allocates heap memory (type llvm::SmallVector<int, 5>)}} |
221 | }; |
222 | |
223 | } // end of namespace clang |
224 | |