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