Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
      2 
      3 typedef unsigned int NSUInteger;
      4 typedef __typeof__(sizeof(int)) size_t;
      5 
      6 void *malloc(size_t);
      7 void *calloc(size_t nmemb, size_t size);
      8 void free(void *);
      9 
     10 void clang_analyzer_eval(int);
     11 
     12 @interface A
     13 - (NSUInteger)foo;
     14 @end
     15 
     16 NSUInteger 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)
     36 void test_PR10163(float);
     37 void PR10163 (void) {
     38   float x[2] = {0};
     39   test_PR10163(x[1]); // no-warning  
     40 }
     41 
     42 
     43 typedef struct {
     44   float x;
     45   float y;
     46   float z;
     47 } Point;
     48 typedef struct {
     49   Point origin;
     50   int size;
     51 } Circle;
     52 
     53 Point 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 
     61 void 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 
     78 void 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 
     87 typedef struct {
     88   int x;
     89   int y;
     90   int z;
     91 } IntPoint;
     92 typedef struct {
     93   IntPoint origin;
     94   int size;
     95 } IntCircle;
     96 
     97 IntPoint 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 
    105 void 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 
    128 void 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 
    140 void 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 
    152 typedef struct {
    153   int x;
    154   int y;
    155 } IntPoint2D;
    156 typedef struct {
    157   IntPoint2D origin;
    158   int size;
    159 } IntCircle2D;
    160 
    161 IntPoint2D makeIntPoint2D(int x, int y) {
    162   IntPoint2D result;
    163   result.x = x;
    164   result.y = y;
    165   return result;
    166 }
    167 
    168 void 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 
    178 void 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 
    188 void 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 
    205 void 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 
    215 void 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 
    229 void 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 
    242 void 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 
    255 void 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 
    270 void 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