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 
temporarayStringToStringRefAssignmentTest()162 void temporarayStringToStringRefAssignmentTest() {
163   // TODO: Emit a warning.
164   llvm::StringRef Ref = std::string("Yimmy yummy test.");
165 }
166 
assigningStringToStringRefWithLongerLifetimeTest()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 
getTemporaryString()176 std::string getTemporaryString() {
177   return "One two three.";
178 }
179 
assigningTempStringFromFunctionToStringRefTest()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