1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s 2 3void clang_analyzer_eval(int); 4 5@interface Root { 6@public 7 int uniqueID; 8} 9 10- (void)refreshID; 11@end 12 13void 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 43struct 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 135int 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