uninit-vals.m revision 4d25b51d582bc7a6a4d83be1642be2f4e812beef
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} Point; 47typedef struct { 48 Point origin; 49 int size; 50} Circle; 51 52Point makePoint(float x, float y) { 53 Point result; 54 result.x = x; 55 result.y = y; 56 return result; 57} 58 59void PR14765_test() { 60 Circle *testObj = calloc(sizeof(Circle), 1); 61 62 clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}} 63 64 testObj->origin = makePoint(0.0, 0.0); 65 if (testObj->size > 0) { ; } // warning occurs here 66 67 // FIXME: Assigning to 'testObj->origin' kills the default binding for the 68 // whole region, meaning that we've forgotten that testObj->size should also 69 // default to 0. Tracked by <rdar://problem/12701038>. 70 // This should be TRUE. 71 clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}} 72 73 free(testObj); 74} 75 76void PR14765_argument(Circle *testObj) { 77 int oldSize = testObj->size; 78 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} 79 80 testObj->origin = makePoint(0.0, 0.0); 81 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} 82} 83 84 85typedef struct { 86 int x; 87 int y; 88} IntPoint; 89typedef struct { 90 IntPoint origin; 91 int size; 92} IntCircle; 93 94IntPoint makeIntPoint(int x, int y) { 95 IntPoint result; 96 result.x = x; 97 result.y = y; 98 return result; 99} 100 101void PR14765_test_int() { 102 IntCircle *testObj = calloc(sizeof(IntCircle), 1); 103 104 clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}} 105 clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}} 106 clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}} 107 108 testObj->origin = makeIntPoint(1, 2); 109 if (testObj->size > 0) { ; } // warning occurs here 110 111 // FIXME: Assigning to 'testObj->origin' kills the default binding for the 112 // whole region, meaning that we've forgotten that testObj->size should also 113 // default to 0. Tracked by <rdar://problem/12701038>. 114 // This should be TRUE. 115 clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}} 116 clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}} 117 clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}} 118 119 free(testObj); 120} 121 122void PR14765_argument_int(IntCircle *testObj) { 123 int oldSize = testObj->size; 124 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} 125 126 testObj->origin = makeIntPoint(1, 2); 127 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}} 128 clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}} 129 clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}} 130} 131 132 133void rdar13292559(Circle input) { 134 extern void useCircle(Circle); 135 136 Circle obj = input; 137 useCircle(obj); // no-warning 138 139 // This generated an "uninitialized 'size' field" warning for a (short) while. 140 obj.origin = makePoint(0.0, 0.0); 141 useCircle(obj); // no-warning 142} 143 144