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