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