diff options
Diffstat (limited to 'test/Analysis/ivars.m')
-rw-r--r-- | test/Analysis/ivars.m | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/test/Analysis/ivars.m b/test/Analysis/ivars.m new file mode 100644 index 0000000..42e92d2 --- /dev/null +++ b/test/Analysis/ivars.m @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s + +void clang_analyzer_eval(int); + +@interface Root { +@public + int uniqueID; +} + +- (void)refreshID; +@end + +void testInvalidation(Root *obj) { + int savedID = obj->uniqueID; + clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{TRUE}} + + [obj refreshID]; + clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{UNKNOWN}} +} + + +@interface Child : Root +@end + +@implementation Child +- (void)testSuperInvalidation { + int savedID = self->uniqueID; + clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{TRUE}} + + [super refreshID]; + clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{UNKNOWN}} +} +@end + + +@interface ManyIvars { + struct S { int a, b; } s; + int c; + int d; +} +@end + +struct S makeS(); + +@implementation ManyIvars + +- (void)testMultipleIvarInvalidation:(int)useConstraints { + if (useConstraints) { + if (s.a != 1) return; + if (s.b != 2) return; + if (c != 3) return; + if (d != 4) return; + return; + } else { + s.a = 1; + s.b = 2; + c = 3; + d = 4; + } + + clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 4); // expected-warning{{TRUE}} + + d = 0; + + clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 0); // expected-warning{{TRUE}} + + d = 4; + s = makeS(); + + clang_analyzer_eval(s.a == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 4); // expected-warning{{TRUE}} + + s.a = 1; + + clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 4); // expected-warning{{TRUE}} +} + ++ (void)testMultipleIvarInvalidation:(int)useConstraints + forObject:(ManyIvars *)obj { + if (useConstraints) { + if (obj->s.a != 1) return; + if (obj->s.b != 2) return; + if (obj->c != 3) return; + if (obj->d != 4) return; + return; + } else { + obj->s.a = 1; + obj->s.b = 2; + obj->c = 3; + obj->d = 4; + } + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}} + + obj->d = 0; + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 0); // expected-warning{{TRUE}} + + obj->d = 4; + obj->s = makeS(); + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}} + + obj->s.a = 1; + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}} +} + +@end |