[clang-cl] Ignore /Wv and /Wv:17 flags
[llvm-project.git] / clang / test / Analysis / const-method-call.cpp
blob8e1fd3b125f0e2cf8ae9a0f7d6b4bb214e26b384
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s
3 void clang_analyzer_eval(bool);
5 struct A {
6 int x;
7 void foo() const;
8 void bar();
10 void testImplicitThisSyntax() {
11 x = 3;
12 foo();
13 clang_analyzer_eval(x == 3); // expected-warning{{TRUE}}
14 bar();
15 clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
19 struct B {
20 mutable int mut;
21 void foo() const;
24 struct C {
25 int *p;
26 void foo() const;
29 struct MutBase {
30 mutable int b_mut;
33 struct MutDerived : MutBase {
34 void foo() const;
37 struct PBase {
38 int *p;
41 struct PDerived : PBase {
42 void foo() const;
45 struct Inner {
46 int x;
47 int *p;
48 void bar() const;
51 struct Outer {
52 int x;
53 Inner in;
54 void foo() const;
57 void checkThatConstMethodWithoutDefinitionDoesNotInvalidateObject() {
58 A t;
59 t.x = 3;
60 t.foo();
61 clang_analyzer_eval(t.x == 3); // expected-warning{{TRUE}}
62 // Test non-const does invalidate
63 t.bar();
64 clang_analyzer_eval(t.x); // expected-warning{{UNKNOWN}}
67 void checkThatConstMethodDoesInvalidateMutableFields() {
68 B t;
69 t.mut = 4;
70 t.foo();
71 clang_analyzer_eval(t.mut); // expected-warning{{UNKNOWN}}
74 void checkThatConstMethodDoesInvalidatePointedAtMemory() {
75 int x = 1;
76 C t;
77 t.p = &x;
78 t.foo();
79 clang_analyzer_eval(x); // expected-warning{{UNKNOWN}}
80 clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}}
83 void checkThatConstMethodDoesInvalidateInheritedMutableFields() {
84 MutDerived t;
85 t.b_mut = 4;
86 t.foo();
87 clang_analyzer_eval(t.b_mut); // expected-warning{{UNKNOWN}}
90 void checkThatConstMethodDoesInvalidateInheritedPointedAtMemory() {
91 int x = 1;
92 PDerived t;
93 t.p = &x;
94 t.foo();
95 clang_analyzer_eval(x); // expected-warning{{UNKNOWN}}
96 clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}}
99 void checkThatConstMethodDoesInvalidateContainedPointedAtMemory() {
100 int x = 1;
101 Outer t;
102 t.x = 2;
103 t.in.p = &x;
104 t.foo();
105 clang_analyzer_eval(x); // expected-warning{{UNKNOWN}}
106 clang_analyzer_eval(t.x == 2); // expected-warning{{TRUE}}
107 clang_analyzer_eval(t.in.p == &x); // expected-warning{{TRUE}}
110 void checkThatContainedConstMethodDoesNotInvalidateObjects() {
111 Outer t;
112 t.x = 1;
113 t.in.x = 2;
114 t.in.bar();
115 clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}}
116 clang_analyzer_eval(t.in.x == 2); // expected-warning{{TRUE}}
119 void checkPointerTypedThisExpression(A *a) {
120 a->x = 3;
121 a->foo();
122 clang_analyzer_eval(a->x == 3); // expected-warning{{TRUE}}
123 a->bar();
124 clang_analyzer_eval(a->x == 3); // expected-warning{{UNKNOWN}}
127 void checkReferenceTypedThisExpression(A &a) {
128 a.x = 3;
129 a.foo();
130 clang_analyzer_eval(a.x == 3); // expected-warning{{TRUE}}
131 a.bar();
132 clang_analyzer_eval(a.x == 3); // expected-warning{{UNKNOWN}}
135 // --- Versions of the above tests where the const method is inherited --- //
137 struct B1 {
138 void foo() const;
141 struct D1 : public B1 {
142 int x;
145 struct D2 : public B1 {
146 mutable int mut;
149 struct D3 : public B1 {
150 int *p;
153 struct DInner : public B1 {
154 int x;
155 int *p;
158 struct DOuter : public B1 {
159 int x;
160 DInner in;
163 void checkThatInheritedConstMethodDoesNotInvalidateObject() {
164 D1 t;
165 t.x = 1;
166 t.foo();
167 clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}}
170 void checkThatInheritedConstMethodDoesInvalidateMutableFields() {
171 D2 t;
172 t.mut = 1;
173 t.foo();
174 clang_analyzer_eval(t.mut); // expected-warning{{UNKNOWN}}
177 void checkThatInheritedConstMethodDoesInvalidatePointedAtMemory() {
178 int x = 1;
179 D3 t;
180 t.p = &x;
181 t.foo();
182 clang_analyzer_eval(x); // expected-warning{{UNKNOWN}}
183 clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}}
186 void checkThatInheritedConstMethodDoesInvalidateContainedPointedAtMemory() {
187 int x = 1;
188 DOuter t;
189 t.x = 2;
190 t.in.x = 3;
191 t.in.p = &x;
192 t.foo();
193 clang_analyzer_eval(x); // expected-warning{{UNKNOWN}}
194 clang_analyzer_eval(t.x == 2); // expected-warning{{TRUE}}
195 clang_analyzer_eval(t.in.x == 3); // expected-warning{{TRUE}}
196 clang_analyzer_eval(t.in.p == &x); // expected-warning{{TRUE}}
199 void checkThatInheritedContainedConstMethodDoesNotInvalidateObjects() {
200 DOuter t;
201 t.x = 1;
202 t.in.x = 2;
203 t.in.foo();
204 clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}}
205 clang_analyzer_eval(t.in.x == 2); // expected-warning{{TRUE}}
208 // --- PR21606 --- //
210 struct s1 {
211 void g(const int *i) const;
214 struct s2 {
215 void f(int *i) {
216 m_i = i;
217 m_s.g(m_i);
218 if (m_i)
219 *i = 42; // no-warning
222 int *m_i;
223 s1 m_s;
226 void PR21606()
228 s2().f(0);
231 // --- PR25392 --- //
233 struct HasConstMemberFunction {
234 public:
235 void constMemberFunction() const;
238 HasConstMemberFunction hasNoReturn() { } // expected-warning {{non-void function does not return a value}}
240 void testUnknownWithConstMemberFunction() {
241 hasNoReturn().constMemberFunction();
244 void testNonRegionLocWithConstMemberFunction() {
245 (*((HasConstMemberFunction *)(&&label))).constMemberFunction();
247 label: return;
250 // FIXME
251 // When there is a circular reference to an object and a const method is called
252 // the object is not invalidated because TK_PreserveContents has already been
253 // set.
254 struct Outer2;
256 struct InnerWithRef {
257 Outer2 *ref;
260 struct Outer2 {
261 int x;
262 InnerWithRef in;
263 void foo() const;
266 void checkThatConstMethodCallDoesInvalidateObjectForCircularReferences() {
267 Outer2 t;
268 t.x = 1;
269 t.in.ref = &t;
270 t.foo();
271 // FIXME: Should be UNKNOWN.
272 clang_analyzer_eval(t.x); // expected-warning{{TRUE}}