xref: /aosp_15_r20/external/clang/test/Analysis/ivars.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
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