]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/call-invalidation.cpp
Vendor import of clang trunk r300422:
[FreeBSD/FreeBSD.git] / test / Analysis / call-invalidation.cpp
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
2
3 void clang_analyzer_eval(bool);
4
5 void usePointer(int * const *);
6 void useReference(int * const &);
7
8 void testPointer() {
9   int x;
10   int *p;
11
12   p = &x;
13   x = 42;
14   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
15   usePointer(&p);
16   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
17
18   p = &x;
19   x = 42;
20   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
21   useReference(p);
22   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
23
24   int * const cp1 = &x;
25   x = 42;
26   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
27   usePointer(&cp1);
28   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
29
30   int * const cp2 = &x;
31   x = 42;
32   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
33   useReference(cp2);
34   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
35 }
36
37
38 struct Wrapper {
39   int *ptr;
40 };
41
42 void useStruct(Wrapper &w);
43 void useConstStruct(const Wrapper &w);
44
45 void testPointerStruct() {
46   int x;
47   Wrapper w;
48
49   w.ptr = &x;
50   x = 42;
51   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
52   useStruct(w);
53   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
54
55   w.ptr = &x;
56   x = 42;
57   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
58   useConstStruct(w);
59   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
60 }
61
62
63 struct RefWrapper {
64   int &ref;
65 };
66
67 void useStruct(RefWrapper &w);
68 void useConstStruct(const RefWrapper &w);
69
70 void testReferenceStruct() {
71   int x;
72   RefWrapper w = { x };
73
74   x = 42;
75   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
76   useStruct(w);
77   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
78 }
79
80 // FIXME: This test is split into two functions because region invalidation
81 // does not preserve reference bindings. <rdar://problem/13320347>
82 void testConstReferenceStruct() {
83   int x;
84   RefWrapper w = { x };
85
86   x = 42;
87   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
88   useConstStruct(w);
89   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
90 }
91
92
93 void usePointerPure(int * const *) __attribute__((pure));
94 void usePointerConst(int * const *) __attribute__((const));
95
96 void testPureConst() {
97   extern int global;
98   int x;
99   int *p;
100
101   p = &x;
102   x = 42;
103   global = -5;
104   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
105   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
106
107   usePointerPure(&p);
108   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
109   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
110
111   usePointerConst(&p);
112   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
113   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
114
115   usePointer(&p);
116   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
117   clang_analyzer_eval(global == -5); // expected-warning{{UNKNOWN}}
118 }
119
120
121 struct PlainStruct {
122   int x, y;
123   mutable int z;
124 };
125
126 PlainStruct glob;
127
128 void useAnything(void *);
129 void useAnythingConst(const void *);
130
131 void testInvalidationThroughBaseRegionPointer() {
132   PlainStruct s1;
133   s1.x = 1;
134   s1.z = 1;
135   clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}}
136   clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}}
137   // Not only passing a structure pointer through const pointer parameter,
138   // but also passing a field pointer through const pointer parameter
139   // should preserve the contents of the structure.
140   useAnythingConst(&(s1.y));
141   clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}}
142   // FIXME: Should say "UNKNOWN", because it is not uncommon to
143   // modify a mutable member variable through const pointer.
144   clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}}
145   useAnything(&(s1.y));
146   clang_analyzer_eval(s1.x == 1); // expected-warning{{UNKNOWN}}
147 }
148
149
150 void useFirstConstSecondNonConst(const void *x, void *y);
151 void useFirstNonConstSecondConst(void *x, const void *y);
152
153 void testMixedConstNonConstCalls() {
154   PlainStruct s2;
155   s2.x = 1;
156   useFirstConstSecondNonConst(&(s2.x), &(s2.y));
157   clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}}
158   s2.x = 1;
159   useFirstNonConstSecondConst(&(s2.x), &(s2.y));
160   clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}}
161   s2.y = 1;
162   useFirstConstSecondNonConst(&(s2.x), &(s2.y));
163   clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}}
164   s2.y = 1;
165   useFirstNonConstSecondConst(&(s2.x), &(s2.y));
166   clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}}
167 }