summaryrefslogtreecommitdiffstats
path: root/test/Analysis/ivars.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/ivars.m')
-rw-r--r--test/Analysis/ivars.m132
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
OpenPOWER on IntegriCloud