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