blob: c717da63ee61ab92ffa3b8f6839fabdb0fcaf06f [file] [log] [blame]
Jordan Rosed72f56d2012-07-31 02:05:30 +00001// 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
Jordan Rose1e934432012-08-09 22:55:51 +000034
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
Jordan Rose991bcb42012-09-22 01:24:38 +0000133
134
135int testNull(Root *obj) {
136 if (obj) return 0;
137
Jordan Rosee606e3d2012-10-01 19:07:22 +0000138 int *x = &obj->uniqueID;
139 return *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
Jordan Rose991bcb42012-09-22 01:24:38 +0000140}