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