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