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 
183 namespace PR31592 {
184 struct C {
185    C() : f("}") { } // no-crash
186    const char(&f)[2];
187 };
188 }
189 
190 namespace CXX_initializer_lists {
191 struct C {
192   C(std::initializer_list<int *> list);
193 };
194 void testPointerEscapeIntoLists() {
195   C empty{}; // no-crash
196 
197   // Do not warn that 'x' leaks. It might have been deleted by
198   // the destructor of 'c'.
199   int *x = new int;
200   C c{x}; // no-warning
201 }
202 
203 void testPassListsWithExplicitConstructors() {
204   (void)(std::initializer_list<int>){12}; // no-crash
205 }
206 }
207 
208 namespace CXX17_aggregate_construction {
209 struct A {
210   A();
211 };
212 
213 struct B: public A {
214 };
215 
216 struct C: public B {
217 };
218 
219 struct D: public virtual A {
220 };
221 
222 // In C++17, classes B and C are aggregates, so they will be constructed
223 // without actually calling their trivial constructor. Used to crash.
224 void foo() {
225   B b = {}; // no-crash
226   const B &bl = {}; // no-crash
227   B &&br = {}; // no-crash
228 
229   C c = {}; // no-crash
230   const C &cl = {}; // no-crash
231   C &&cr = {}; // no-crash
232 
233   D d = {}; // no-crash
234 
235 #ifdef CPLUSPLUS17
236   C cd = {{}}; // no-crash
237   const C &cdl = {{}}; // no-crash
238   C &&cdr = {{}}; // no-crash
239 
240   const B &bll = {{}}; // no-crash
241   const B &bcl = C({{}}); // no-crash
242   B &&bcr = C({{}}); // no-crash
243 #endif
244 }
245 }
246