1*f4a2713aSLionel Sambuc// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
2*f4a2713aSLionel Sambuc
3*f4a2713aSLionel Sambuctypedef unsigned int NSUInteger;
4*f4a2713aSLionel Sambuctypedef __typeof__(sizeof(int)) size_t;
5*f4a2713aSLionel Sambuc
6*f4a2713aSLionel Sambucvoid *malloc(size_t);
7*f4a2713aSLionel Sambucvoid *calloc(size_t nmemb, size_t size);
8*f4a2713aSLionel Sambucvoid free(void *);
9*f4a2713aSLionel Sambuc
10*f4a2713aSLionel Sambucvoid clang_analyzer_eval(int);
11*f4a2713aSLionel Sambuc
12*f4a2713aSLionel Sambuc@interface A
13*f4a2713aSLionel Sambuc- (NSUInteger)foo;
14*f4a2713aSLionel Sambuc@end
15*f4a2713aSLionel Sambuc
16*f4a2713aSLionel SambucNSUInteger f8(A* x){
17*f4a2713aSLionel Sambuc  const NSUInteger n = [x foo];
18*f4a2713aSLionel Sambuc  int* bogus;
19*f4a2713aSLionel Sambuc
20*f4a2713aSLionel Sambuc  if (n > 0) {    // tests const cast transfer function logic
21*f4a2713aSLionel Sambuc    NSUInteger i;
22*f4a2713aSLionel Sambuc
23*f4a2713aSLionel Sambuc    for (i = 0; i < n; ++i)
24*f4a2713aSLionel Sambuc      bogus = 0;
25*f4a2713aSLionel Sambuc
26*f4a2713aSLionel Sambuc    if (bogus)  // no-warning
27*f4a2713aSLionel Sambuc      return n+1;
28*f4a2713aSLionel Sambuc  }
29*f4a2713aSLionel Sambuc
30*f4a2713aSLionel Sambuc  return n;
31*f4a2713aSLionel Sambuc}
32*f4a2713aSLionel Sambuc
33*f4a2713aSLionel Sambuc
34*f4a2713aSLionel Sambuc// PR10163 -- don't warn for default-initialized float arrays.
35*f4a2713aSLionel Sambuc// (An additional test is in uninit-vals-ps-region.m)
36*f4a2713aSLionel Sambucvoid test_PR10163(float);
37*f4a2713aSLionel Sambucvoid PR10163 (void) {
38*f4a2713aSLionel Sambuc  float x[2] = {0};
39*f4a2713aSLionel Sambuc  test_PR10163(x[1]); // no-warning
40*f4a2713aSLionel Sambuc}
41*f4a2713aSLionel Sambuc
42*f4a2713aSLionel Sambuc
43*f4a2713aSLionel Sambuctypedef struct {
44*f4a2713aSLionel Sambuc  float x;
45*f4a2713aSLionel Sambuc  float y;
46*f4a2713aSLionel Sambuc  float z;
47*f4a2713aSLionel Sambuc} Point;
48*f4a2713aSLionel Sambuctypedef struct {
49*f4a2713aSLionel Sambuc  Point origin;
50*f4a2713aSLionel Sambuc  int size;
51*f4a2713aSLionel Sambuc} Circle;
52*f4a2713aSLionel Sambuc
53*f4a2713aSLionel SambucPoint makePoint(float x, float y) {
54*f4a2713aSLionel Sambuc  Point result;
55*f4a2713aSLionel Sambuc  result.x = x;
56*f4a2713aSLionel Sambuc  result.y = y;
57*f4a2713aSLionel Sambuc  result.z = 0.0;
58*f4a2713aSLionel Sambuc  return result;
59*f4a2713aSLionel Sambuc}
60*f4a2713aSLionel Sambuc
61*f4a2713aSLionel Sambucvoid PR14765_test() {
62*f4a2713aSLionel Sambuc  Circle *testObj = calloc(sizeof(Circle), 1);
63*f4a2713aSLionel Sambuc
64*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
65*f4a2713aSLionel Sambuc
66*f4a2713aSLionel Sambuc  testObj->origin = makePoint(0.0, 0.0);
67*f4a2713aSLionel Sambuc  if (testObj->size > 0) { ; } // warning occurs here
68*f4a2713aSLionel Sambuc
69*f4a2713aSLionel Sambuc  // FIXME: Assigning to 'testObj->origin' kills the default binding for the
70*f4a2713aSLionel Sambuc  // whole region, meaning that we've forgotten that testObj->size should also
71*f4a2713aSLionel Sambuc  // default to 0. Tracked by <rdar://problem/12701038>.
72*f4a2713aSLionel Sambuc  // This should be TRUE.
73*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
74*f4a2713aSLionel Sambuc
75*f4a2713aSLionel Sambuc  free(testObj);
76*f4a2713aSLionel Sambuc}
77*f4a2713aSLionel Sambuc
78*f4a2713aSLionel Sambucvoid PR14765_argument(Circle *testObj) {
79*f4a2713aSLionel Sambuc  int oldSize = testObj->size;
80*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
81*f4a2713aSLionel Sambuc
82*f4a2713aSLionel Sambuc  testObj->origin = makePoint(0.0, 0.0);
83*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
84*f4a2713aSLionel Sambuc}
85*f4a2713aSLionel Sambuc
86*f4a2713aSLionel Sambuc
87*f4a2713aSLionel Sambuctypedef struct {
88*f4a2713aSLionel Sambuc  int x;
89*f4a2713aSLionel Sambuc  int y;
90*f4a2713aSLionel Sambuc  int z;
91*f4a2713aSLionel Sambuc} IntPoint;
92*f4a2713aSLionel Sambuctypedef struct {
93*f4a2713aSLionel Sambuc  IntPoint origin;
94*f4a2713aSLionel Sambuc  int size;
95*f4a2713aSLionel Sambuc} IntCircle;
96*f4a2713aSLionel Sambuc
97*f4a2713aSLionel SambucIntPoint makeIntPoint(int x, int y) {
98*f4a2713aSLionel Sambuc  IntPoint result;
99*f4a2713aSLionel Sambuc  result.x = x;
100*f4a2713aSLionel Sambuc  result.y = y;
101*f4a2713aSLionel Sambuc  result.z = 0;
102*f4a2713aSLionel Sambuc  return result;
103*f4a2713aSLionel Sambuc}
104*f4a2713aSLionel Sambuc
105*f4a2713aSLionel Sambucvoid PR14765_test_int() {
106*f4a2713aSLionel Sambuc  IntCircle *testObj = calloc(sizeof(IntCircle), 1);
107*f4a2713aSLionel Sambuc
108*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
109*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
110*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
111*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
112*f4a2713aSLionel Sambuc
113*f4a2713aSLionel Sambuc  testObj->origin = makeIntPoint(1, 2);
114*f4a2713aSLionel Sambuc  if (testObj->size > 0) { ; } // warning occurs here
115*f4a2713aSLionel Sambuc
116*f4a2713aSLionel Sambuc  // FIXME: Assigning to 'testObj->origin' kills the default binding for the
117*f4a2713aSLionel Sambuc  // whole region, meaning that we've forgotten that testObj->size should also
118*f4a2713aSLionel Sambuc  // default to 0. Tracked by <rdar://problem/12701038>.
119*f4a2713aSLionel Sambuc  // This should be TRUE.
120*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
121*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
122*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
123*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
124*f4a2713aSLionel Sambuc
125*f4a2713aSLionel Sambuc  free(testObj);
126*f4a2713aSLionel Sambuc}
127*f4a2713aSLionel Sambuc
128*f4a2713aSLionel Sambucvoid PR14765_argument_int(IntCircle *testObj) {
129*f4a2713aSLionel Sambuc  int oldSize = testObj->size;
130*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
131*f4a2713aSLionel Sambuc
132*f4a2713aSLionel Sambuc  testObj->origin = makeIntPoint(1, 2);
133*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
134*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
135*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
136*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
137*f4a2713aSLionel Sambuc}
138*f4a2713aSLionel Sambuc
139*f4a2713aSLionel Sambuc
140*f4a2713aSLionel Sambucvoid rdar13292559(Circle input) {
141*f4a2713aSLionel Sambuc  extern void useCircle(Circle);
142*f4a2713aSLionel Sambuc
143*f4a2713aSLionel Sambuc  Circle obj = input;
144*f4a2713aSLionel Sambuc  useCircle(obj); // no-warning
145*f4a2713aSLionel Sambuc
146*f4a2713aSLionel Sambuc  // This generated an "uninitialized 'size' field" warning for a (short) while.
147*f4a2713aSLionel Sambuc  obj.origin = makePoint(0.0, 0.0);
148*f4a2713aSLionel Sambuc  useCircle(obj); // no-warning
149*f4a2713aSLionel Sambuc}
150*f4a2713aSLionel Sambuc
151*f4a2713aSLionel Sambuc
152*f4a2713aSLionel Sambuctypedef struct {
153*f4a2713aSLionel Sambuc  int x;
154*f4a2713aSLionel Sambuc  int y;
155*f4a2713aSLionel Sambuc} IntPoint2D;
156*f4a2713aSLionel Sambuctypedef struct {
157*f4a2713aSLionel Sambuc  IntPoint2D origin;
158*f4a2713aSLionel Sambuc  int size;
159*f4a2713aSLionel Sambuc} IntCircle2D;
160*f4a2713aSLionel Sambuc
161*f4a2713aSLionel SambucIntPoint2D makeIntPoint2D(int x, int y) {
162*f4a2713aSLionel Sambuc  IntPoint2D result;
163*f4a2713aSLionel Sambuc  result.x = x;
164*f4a2713aSLionel Sambuc  result.y = y;
165*f4a2713aSLionel Sambuc  return result;
166*f4a2713aSLionel Sambuc}
167*f4a2713aSLionel Sambuc
168*f4a2713aSLionel Sambucvoid testSmallStructsCopiedPerField() {
169*f4a2713aSLionel Sambuc  IntPoint2D a;
170*f4a2713aSLionel Sambuc  a.x = 0;
171*f4a2713aSLionel Sambuc
172*f4a2713aSLionel Sambuc  IntPoint2D b = a;
173*f4a2713aSLionel Sambuc  extern void useInt(int);
174*f4a2713aSLionel Sambuc  useInt(b.x); // no-warning
175*f4a2713aSLionel Sambuc  useInt(b.y); // expected-warning{{uninitialized}}
176*f4a2713aSLionel Sambuc}
177*f4a2713aSLionel Sambuc
178*f4a2713aSLionel Sambucvoid testLargeStructsNotCopiedPerField() {
179*f4a2713aSLionel Sambuc  IntPoint a;
180*f4a2713aSLionel Sambuc  a.x = 0;
181*f4a2713aSLionel Sambuc
182*f4a2713aSLionel Sambuc  IntPoint b = a;
183*f4a2713aSLionel Sambuc  extern void useInt(int);
184*f4a2713aSLionel Sambuc  useInt(b.x); // no-warning
185*f4a2713aSLionel Sambuc  useInt(b.y); // no-warning
186*f4a2713aSLionel Sambuc}
187*f4a2713aSLionel Sambuc
188*f4a2713aSLionel Sambucvoid testSmallStructInLargerStruct() {
189*f4a2713aSLionel Sambuc  IntCircle2D *testObj = calloc(sizeof(IntCircle2D), 1);
190*f4a2713aSLionel Sambuc
191*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
192*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
193*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
194*f4a2713aSLionel Sambuc
195*f4a2713aSLionel Sambuc  testObj->origin = makeIntPoint2D(1, 2);
196*f4a2713aSLionel Sambuc  if (testObj->size > 0) { ; } // warning occurs here
197*f4a2713aSLionel Sambuc
198*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
199*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
200*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
201*f4a2713aSLionel Sambuc
202*f4a2713aSLionel Sambuc  free(testObj);
203*f4a2713aSLionel Sambuc}
204*f4a2713aSLionel Sambuc
205*f4a2713aSLionel Sambucvoid testCopySmallStructIntoArgument(IntCircle2D *testObj) {
206*f4a2713aSLionel Sambuc  int oldSize = testObj->size;
207*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
208*f4a2713aSLionel Sambuc
209*f4a2713aSLionel Sambuc  testObj->origin = makeIntPoint2D(1, 2);
210*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
211*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
212*f4a2713aSLionel Sambuc  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
213*f4a2713aSLionel Sambuc}
214*f4a2713aSLionel Sambuc
215*f4a2713aSLionel Sambucvoid testSmallStructBitfields() {
216*f4a2713aSLionel Sambuc  struct {
217*f4a2713aSLionel Sambuc    int x : 4;
218*f4a2713aSLionel Sambuc    int y : 4;
219*f4a2713aSLionel Sambuc  } a, b;
220*f4a2713aSLionel Sambuc
221*f4a2713aSLionel Sambuc  a.x = 1;
222*f4a2713aSLionel Sambuc  a.y = 2;
223*f4a2713aSLionel Sambuc
224*f4a2713aSLionel Sambuc  b = a;
225*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
226*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
227*f4a2713aSLionel Sambuc}
228*f4a2713aSLionel Sambuc
229*f4a2713aSLionel Sambucvoid testSmallStructBitfieldsFirstUndef() {
230*f4a2713aSLionel Sambuc  struct {
231*f4a2713aSLionel Sambuc    int x : 4;
232*f4a2713aSLionel Sambuc    int y : 4;
233*f4a2713aSLionel Sambuc  } a, b;
234*f4a2713aSLionel Sambuc
235*f4a2713aSLionel Sambuc  a.y = 2;
236*f4a2713aSLionel Sambuc
237*f4a2713aSLionel Sambuc  b = a;
238*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
239*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
240*f4a2713aSLionel Sambuc}
241*f4a2713aSLionel Sambuc
242*f4a2713aSLionel Sambucvoid testSmallStructBitfieldsSecondUndef() {
243*f4a2713aSLionel Sambuc  struct {
244*f4a2713aSLionel Sambuc    int x : 4;
245*f4a2713aSLionel Sambuc    int y : 4;
246*f4a2713aSLionel Sambuc  } a, b;
247*f4a2713aSLionel Sambuc
248*f4a2713aSLionel Sambuc  a.x = 1;
249*f4a2713aSLionel Sambuc
250*f4a2713aSLionel Sambuc  b = a;
251*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
252*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
253*f4a2713aSLionel Sambuc}
254*f4a2713aSLionel Sambuc
255*f4a2713aSLionel Sambucvoid testSmallStructBitfieldsFirstUnnamed() {
256*f4a2713aSLionel Sambuc  struct {
257*f4a2713aSLionel Sambuc    int : 4;
258*f4a2713aSLionel Sambuc    int y : 4;
259*f4a2713aSLionel Sambuc  } a, b, c;
260*f4a2713aSLionel Sambuc
261*f4a2713aSLionel Sambuc  a.y = 2;
262*f4a2713aSLionel Sambuc
263*f4a2713aSLionel Sambuc  b = a;
264*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
265*f4a2713aSLionel Sambuc
266*f4a2713aSLionel Sambuc  b = c;
267*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
268*f4a2713aSLionel Sambuc}
269*f4a2713aSLionel Sambuc
270*f4a2713aSLionel Sambucvoid testSmallStructBitfieldsSecondUnnamed() {
271*f4a2713aSLionel Sambuc  struct {
272*f4a2713aSLionel Sambuc    int x : 4;
273*f4a2713aSLionel Sambuc    int : 4;
274*f4a2713aSLionel Sambuc  } a, b, c;
275*f4a2713aSLionel Sambuc
276*f4a2713aSLionel Sambuc  a.x = 1;
277*f4a2713aSLionel Sambuc
278*f4a2713aSLionel Sambuc  b = a;
279*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
280*f4a2713aSLionel Sambuc
281*f4a2713aSLionel Sambuc  b = c;
282*f4a2713aSLionel Sambuc  clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
283*f4a2713aSLionel Sambuc}
284*f4a2713aSLionel Sambuc
285