xref: /llvm-project/clang/test/Analysis/llvm-conventions.cpp (revision be88539b85204041f727ec6499315884b3d886b0)
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