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