1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++17 -DCPLUSPLUS17 -verify %s
3 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
4 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++17 -DCPLUSPLUS17 -DTEST_INLINABLE_ALLOCATORS -verify %s
5 
6 void clang_analyzer_eval(bool);
7 
8 #include "Inputs/system-header-simulator-cxx.h"
9 
10 class A {
11   int x;
12 public:
13   A();
14 };
15 
16 A::A() : x(0) {
17   clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
18 }
19 
20 
21 class DirectMember {
22   int x;
23 public:
24   DirectMember(int value) : x(value) {}
25 
26   int getX() { return x; }
27 };
28 
29 void testDirectMember() {
30   DirectMember obj(3);
31   clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
32 }
33 
34 
35 class IndirectMember {
36   struct {
37     int x;
38   };
39 public:
40   IndirectMember(int value) : x(value) {}
41 
42   int getX() { return x; }
43 };
44 
45 void testIndirectMember() {
46   IndirectMember obj(3);
47   clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
48 }
49 
50 
51 struct DelegatingConstructor {
52   int x;
53   DelegatingConstructor(int y) { x = y; }
54   DelegatingConstructor() : DelegatingConstructor(42) {}
55 };
56 
57 void testDelegatingConstructor() {
58   DelegatingConstructor obj;
59   clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}
60 }
61 
62 
63 struct RefWrapper {
64   RefWrapper(int *p) : x(*p) {}
65   RefWrapper(int &r) : x(r) {}
66   int &x;
67 };
68 
69 void testReferenceMember() {
70   int *p = 0;
71   RefWrapper X(p); // expected-warning@-7 {{Dereference of null pointer}}
72 }
73 
74 void testReferenceMember2() {
75   int *p = 0;
76   RefWrapper X(*p); // expected-warning {{Forming reference to null pointer}}
77 }
78 
79 
80 extern "C" char *strdup(const char *);
81 
82 class StringWrapper {
83   char *str;
84 public:
85   StringWrapper(const char *input) : str(strdup(input)) {} // no-warning
86 };
87 
88 
89 // PR15070 - Constructing a type containing a non-POD array mistakenly
90 // tried to perform a bind instead of relying on the CXXConstructExpr,
91 // which caused a cast<> failure in RegionStore.
92 namespace DefaultConstructorWithCleanups {
93   class Element {
94   public:
95     int value;
96 
97     class Helper {
98     public:
99       ~Helper();
100     };
101     Element(Helper h = Helper());
102   };
103   class Wrapper {
104   public:
105     Element arr[2];
106 
107     Wrapper();
108   };
109 
110   Wrapper::Wrapper() /* initializers synthesized */ {}
111 
112   int test() {
113     Wrapper w;
114     return w.arr[0].value; // no-warning
115   }
116 }
117 
118 namespace DefaultMemberInitializers {
119   struct Wrapper {
120     int value = 42;
121 
122     Wrapper() {}
123     Wrapper(int x) : value(x) {}
124     Wrapper(bool) {}
125   };
126 
127   void test() {
128     Wrapper w1;
129     clang_analyzer_eval(w1.value == 42); // expected-warning{{TRUE}}
130 
131     Wrapper w2(50);
132     clang_analyzer_eval(w2.value == 50); // expected-warning{{TRUE}}
133 
134     Wrapper w3(false);
135     clang_analyzer_eval(w3.value == 42); // expected-warning{{TRUE}}
136   }
137 
138   struct StringWrapper {
139     const char s[4] = "abc";
140     const char *p = "xyz";
141 
142     StringWrapper(bool) {}
143   };
144 
145   void testString() {
146     StringWrapper w(true);
147     clang_analyzer_eval(w.s[1] == 'b'); // expected-warning{{TRUE}}
148     clang_analyzer_eval(w.p[1] == 'y'); // expected-warning{{TRUE}}
149   }
150 }
151 
152 namespace ReferenceInitialization {
153   struct OtherStruct {
154     OtherStruct(int i);
155     ~OtherStruct();
156   };
157 
158   struct MyStruct {
159     MyStruct(int i);
160     MyStruct(OtherStruct os);
161 
162     void method() const;
163   };
164 
165   void referenceInitializeLocal() {
166     const MyStruct &myStruct(5);
167     myStruct.method(); // no-warning
168   }
169 
170   void referenceInitializeMultipleLocals() {
171     const MyStruct &myStruct1(5), myStruct2(5), &myStruct3(5);
172     myStruct1.method(); // no-warning
173     myStruct2.method(); // no-warning
174     myStruct3.method(); // no-warning
175   }
176 
177   void referenceInitializeLocalWithCleanup() {
178     const MyStruct &myStruct(OtherStruct(5));
179     myStruct.method(); // no-warning
180   }
181 
182   struct HasMyStruct {
183     const MyStruct &ms; // expected-note {{reference member declared here}}
184     const MyStruct &msWithCleanups; // expected-note {{reference member declared here}}
185 
186     // clang's Sema issues a warning when binding a reference member to a
187     // temporary value.
188     HasMyStruct() : ms(5), msWithCleanups(OtherStruct(5)) {
189         // expected-warning@-1 {{binding reference member 'ms' to a temporary value}}
190         // expected-warning@-2 {{binding reference member 'msWithCleanups' to a temporary value}}
191 
192       // At this point the members are not garbage so we should not expect an
193       // analyzer warning here even though binding a reference member
194       // to a member is a terrible idea.
195       ms.method(); // no-warning
196       msWithCleanups.method(); // no-warning
197     }
198   };
199 
200   void referenceInitializeField() {
201     HasMyStruct hms;
202   }
203 
204 };
205 
206 namespace PR31592 {
207 struct C {
208    C() : f("}") { } // no-crash
209    const char(&f)[2];
210 };
211 }
212 
213 namespace CXX_initializer_lists {
214 struct C {
215   C(std::initializer_list<int *> list);
216 };
217 void testPointerEscapeIntoLists() {
218   C empty{}; // no-crash
219 
220   // Do not warn that 'x' leaks. It might have been deleted by
221   // the destructor of 'c'.
222   int *x = new int;
223   C c{x}; // no-warning
224 }
225 
226 void testPassListsWithExplicitConstructors() {
227   (void)(std::initializer_list<int>){12}; // no-crash
228 }
229 }
230 
231 namespace CXX17_aggregate_construction {
232 struct A {
233   A();
234 };
235 
236 struct B: public A {
237 };
238 
239 struct C: public B {
240 };
241 
242 struct D: public virtual A {
243 };
244 
245 // In C++17, classes B and C are aggregates, so they will be constructed
246 // without actually calling their trivial constructor. Used to crash.
247 void foo() {
248   B b = {}; // no-crash
249   const B &bl = {}; // no-crash
250   B &&br = {}; // no-crash
251 
252   C c = {}; // no-crash
253   const C &cl = {}; // no-crash
254   C &&cr = {}; // no-crash
255 
256   D d = {}; // no-crash
257 
258 #ifdef CPLUSPLUS17
259   C cd = {{}}; // no-crash
260   const C &cdl = {{}}; // no-crash
261   C &&cdr = {{}}; // no-crash
262 
263   const B &bll = {{}}; // no-crash
264   const B &bcl = C({{}}); // no-crash
265   B &&bcr = C({{}}); // no-crash
266 #endif
267 }
268 }
269