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 template <typename T> struct isPodLike;
156 template <> struct isPodLike<StringRef> { static const bool value = true; };
157 
158 } // end of namespace llvm
159 
160 //===----------------------------------------------------------------------===//
161 // Tests for StringRef.
162 //===----------------------------------------------------------------------===//
163 
temporarayStringToStringRefAssignmentTest()164 void temporarayStringToStringRefAssignmentTest() {
165   // TODO: Emit a warning.
166   llvm::StringRef Ref = std::string("Yimmy yummy test.");
167 }
168 
assigningStringToStringRefWithLongerLifetimeTest()169 void assigningStringToStringRefWithLongerLifetimeTest() {
170   llvm::StringRef Ref;
171   {
172     // TODO: Emit a warning.
173     std::string TmpStr("This is a fine string.");
174     Ref = TmpStr;
175   }
176 }
177 
getTemporaryString()178 std::string getTemporaryString() {
179   return "One two three.";
180 }
181 
assigningTempStringFromFunctionToStringRefTest()182 void assigningTempStringFromFunctionToStringRefTest() {
183   // TODO: Emit a warning.
184   llvm::StringRef Ref = getTemporaryString();
185 }
186 
187 //===----------------------------------------------------------------------===//
188 // Forward declaration for Clang AST nodes.
189 //===----------------------------------------------------------------------===//
190 
191 namespace llvm {
192 
193 template <class T, int Size>
194 struct SmallVector {};
195 
196 } // end of namespace llvm
197 
198 namespace clang {
199 
200 struct Type;
201 struct Decl;
202 struct Stmt;
203 struct Attr;
204 
205 } // end of namespace clang
206 
207 //===----------------------------------------------------------------------===//
208 // Tests for Clang AST nodes.
209 //===----------------------------------------------------------------------===//
210 
211 namespace clang {
212 
213 struct Type {
214   std::string str; // expected-warning{{AST class 'Type' has a field 'str' that allocates heap memory (type std::string)}}
215 };
216 
217 } // end of namespace clang
218 
219 namespace clang {
220 
221 struct Decl {
222   llvm::SmallVector<int, 5> Vec; // expected-warning{{AST class 'Decl' has a field 'Vec' that allocates heap memory (type llvm::SmallVector<int, 5>)}}
223 };
224 
225 } // end of namespace clang
226