1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
2 // RUN: -analyzer-checker=debug.ExprInspection -verify\
3 // RUN: -Wno-tautological-compare\
5 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
6 // RUN: -analyzer-checker=debug.ExprInspection -verify\
7 // RUN: -Wno-tautological-compare\
8 // RUN: -x c++ -std=c++14 %s
9 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
10 // RUN: -analyzer-checker=debug.ExprInspection -verify\
11 // RUN: -Wno-tautological-compare\
12 // RUN: -x c++ -std=c++17 %s
13 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
14 // RUN: -analyzer-checker=debug.ExprInspection -verify\
15 // RUN: -Wno-tautological-compare\
16 // RUN: -DINLINE -x c %s
17 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
18 // RUN: -analyzer-checker=debug.ExprInspection -verify\
19 // RUN: -Wno-tautological-compare\
20 // RUN: -DINLINE -x c++ -std=c++14 %s
21 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
22 // RUN: -analyzer-checker=debug.ExprInspection -verify\
23 // RUN: -Wno-tautological-compare\
24 // RUN: -DINLINE -x c++ -std=c++17 %s
26 void clang_analyzer_eval(int);
32 const struct S
*getThis() const { return this; }
33 const struct S
*operator +() const { return this; }
35 bool check() const { return this == this; }
36 bool operator !() const { return this != this; }
38 int operator *() const { return field
; }
43 const struct S
*operator -(const struct S
&s
) { return &s
; }
44 bool operator ~(const struct S
&s
) { return (&s
) != &s
; }
58 void testAssignment(void) {
61 if (s
.field
!= 42) return;
62 clang_analyzer_eval(s
.field
== 42); // expected-warning{{TRUE}}
65 clang_analyzer_eval(s
.field
== 0); // expected-warning{{TRUE}}
68 clang_analyzer_eval(s
.getThis() == &s
); // expected-warning{{TRUE}}
69 clang_analyzer_eval(+s
== &s
); // expected-warning{{TRUE}}
70 clang_analyzer_eval(-s
== &s
); // expected-warning{{TRUE}}
72 clang_analyzer_eval(s
.check()); // expected-warning{{TRUE}}
73 clang_analyzer_eval(!s
); // expected-warning{{FALSE}}
74 clang_analyzer_eval(~s
); // expected-warning{{FALSE}}
76 clang_analyzer_eval(*s
== 0); // expected-warning{{TRUE}}
81 void testImmediateUse(void) {
85 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
88 clang_analyzer_eval((void *)getS().getThis() == (void *)&x
); // expected-warning{{FALSE}}
89 clang_analyzer_eval((void *)+getS() == (void *)&x
); // expected-warning{{FALSE}}
90 clang_analyzer_eval((void *)-getS() == (void *)&x
); // expected-warning{{FALSE}}
92 clang_analyzer_eval(getS().check()); // expected-warning{{TRUE}}
93 clang_analyzer_eval(!getS()); // expected-warning{{FALSE}}
94 clang_analyzer_eval(~getS()); // expected-warning{{FALSE}}
98 int getConstrainedField(struct S s
) {
99 if (s
.field
!= 42) return 42;
103 int getAssignedField(struct S s
) {
108 void testArgument(void) {
109 clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
110 clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
113 void testImmediateUseParens(void) {
114 int x
= ((getS())).field
;
117 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
119 clang_analyzer_eval(getConstrainedField(((getS()))) == 42); // expected-warning{{TRUE}}
120 clang_analyzer_eval(getAssignedField(((getS()))) == 42); // expected-warning{{TRUE}}
123 clang_analyzer_eval(((getS())).check()); // expected-warning{{TRUE}}
124 clang_analyzer_eval(!((getS()))); // expected-warning{{FALSE}}
125 clang_analyzer_eval(~((getS()))); // expected-warning{{FALSE}}
130 //--------------------
132 //--------------------
135 void testReferenceAssignment() {
138 if (s
.field
!= 42) return;
139 clang_analyzer_eval(s
.field
== 42); // expected-warning{{TRUE}}
141 clang_analyzer_eval(s
.getThis() == &s
); // expected-warning{{TRUE}}
142 clang_analyzer_eval(+s
== &s
); // expected-warning{{TRUE}}
144 clang_analyzer_eval(s
.check()); // expected-warning{{TRUE}}
145 clang_analyzer_eval(!s
); // expected-warning{{FALSE}}
146 clang_analyzer_eval(~s
); // expected-warning{{FALSE}}
148 clang_analyzer_eval(*s
== 42); // expected-warning{{TRUE}}
152 int getConstrainedFieldRef(const S
&s
) {
153 if (s
.field
!= 42) return 42;
157 bool checkThis(const S
&s
) {
158 return s
.getThis() == &s
;
161 bool checkThisOp(const S
&s
) {
165 bool checkThisStaticOp(const S
&s
) {
169 void testReferenceArgument() {
170 clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
171 clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
172 clang_analyzer_eval(checkThisOp(getS())); // expected-warning{{TRUE}}
173 clang_analyzer_eval(checkThisStaticOp(getS())); // expected-warning{{TRUE}}
177 int getConstrainedFieldOp(S s
) {
178 if (*s
!= 42) return 42;
182 int getConstrainedFieldRefOp(const S
&s
) {
183 if (*s
!= 42) return 42;
187 void testImmediateUseOp() {
190 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
192 clang_analyzer_eval(getConstrainedFieldOp(getS()) == 42); // expected-warning{{TRUE}}
193 clang_analyzer_eval(getConstrainedFieldRefOp(getS()) == 42); // expected-warning{{TRUE}}
196 namespace EmptyClass
{
200 Base(int& x
) : x(x
) {}
203 struct Derived
: public Base
{
204 Derived(int& x
) : Base(x
) {}
206 void operator=(int a
) { x
= a
; }
209 Derived
ref(int& a
) { return Derived(a
); }
211 // There used to be a warning here, because analyzer treated Derived as empty.
215 return a
; // no warning
219 #if __cplusplus >= 201703L
220 namespace aggregate_inheritance_cxx17
{
239 clang_analyzer_eval(d
.x
== 1); // expected-warning{{TRUE}}
240 clang_analyzer_eval(d
.y
== 2); // expected-warning{{TRUE}}
241 clang_analyzer_eval(d
.z
== 3); // expected-warning{{TRUE}}
242 clang_analyzer_eval(d
.w
== 4); // expected-warning{{TRUE}}
244 } // namespace aggregate_inheritance_cxx17
247 namespace flex_array_inheritance_cxx17
{
249 int flexible_array
[];
263 } // namespace flex_array_inheritance_cxx17