Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s
      2 
      3 void clang_analyzer_eval(int);
      4 
      5 @interface Root {
      6 @public
      7   int uniqueID;
      8 }
      9 
     10 - (void)refreshID;
     11 @end
     12 
     13 void testInvalidation(Root *obj) {
     14   int savedID = obj->uniqueID;
     15   clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{TRUE}}
     16 
     17   [obj refreshID];
     18   clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{UNKNOWN}}
     19 }
     20 
     21 
     22 @interface Child : Root
     23 @end
     24 
     25 @implementation Child
     26 - (void)testSuperInvalidation {
     27   int savedID = self->uniqueID;
     28   clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{TRUE}}
     29 
     30   [super refreshID];
     31   clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{UNKNOWN}}
     32 }
     33 @end
     34 
     35 
     36 @interface ManyIvars {
     37   struct S { int a, b; } s;
     38   int c;
     39   int d;
     40 }
     41 @end
     42 
     43 struct S makeS();
     44 
     45 @implementation ManyIvars
     46 
     47 - (void)testMultipleIvarInvalidation:(int)useConstraints {
     48   if (useConstraints) {
     49     if (s.a != 1) return;
     50     if (s.b != 2) return;
     51     if (c != 3) return;
     52     if (d != 4) return;
     53     return;
     54   } else {
     55     s.a = 1;
     56     s.b = 2;
     57     c = 3;
     58     d = 4;
     59   }
     60 
     61   clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}}
     62   clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}}
     63   clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
     64   clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}
     65 
     66   d = 0;
     67 
     68   clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}}
     69   clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}}
     70   clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
     71   clang_analyzer_eval(d == 0); // expected-warning{{TRUE}}
     72 
     73   d = 4;
     74   s = makeS();
     75 
     76   clang_analyzer_eval(s.a == 1); // expected-warning{{UNKNOWN}}
     77   clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}}
     78   clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
     79   clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}
     80 
     81   s.a = 1;
     82 
     83   clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}}
     84   clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}}
     85   clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
     86   clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}
     87 }
     88 
     89 + (void)testMultipleIvarInvalidation:(int)useConstraints
     90                            forObject:(ManyIvars *)obj {
     91   if (useConstraints) {
     92     if (obj->s.a != 1) return;
     93     if (obj->s.b != 2) return;
     94     if (obj->c != 3) return;
     95     if (obj->d != 4) return;
     96     return;
     97   } else {
     98     obj->s.a = 1;
     99     obj->s.b = 2;
    100     obj->c = 3;
    101     obj->d = 4;
    102   }
    103 
    104   clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}}
    105   clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}}
    106   clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
    107   clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}}
    108 
    109   obj->d = 0;
    110 
    111   clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}}
    112   clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}}
    113   clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
    114   clang_analyzer_eval(obj->d == 0); // expected-warning{{TRUE}}
    115 
    116   obj->d = 4;
    117   obj->s = makeS();
    118 
    119   clang_analyzer_eval(obj->s.a == 1); // expected-warning{{UNKNOWN}}
    120   clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}}
    121   clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
    122   clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}}
    123 
    124   obj->s.a = 1;
    125 
    126   clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}}
    127   clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}}
    128   clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
    129   clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}}
    130 }
    131 
    132 @end
    133 
    134 
    135 int testNull(Root *obj) {
    136   if (obj) return 0;
    137 
    138   int *x = &obj->uniqueID;
    139   return *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
    140 }
    141