1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
3 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
4 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
6 void clang_analyzer_eval(int);
12 const struct S *getThis() const { return this; }
13 const struct S *operator +() const { return this; }
15 bool check() const { return this == this; }
16 bool operator !() const { return this != this; }
18 int operator *() const { return field; }
23 const struct S *operator -(const struct S &s) { return &s; }
24 bool operator ~(const struct S &s) { return (&s) != &s; }
38 void testAssignment() {
41 if (s.field != 42) return;
42 clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
45 clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}}
48 clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
49 clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
50 clang_analyzer_eval(-s == &s); // expected-warning{{TRUE}}
52 clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
53 clang_analyzer_eval(!s); // expected-warning{{FALSE}}
54 clang_analyzer_eval(~s); // expected-warning{{FALSE}}
56 clang_analyzer_eval(*s == 0); // expected-warning{{TRUE}}
61 void testImmediateUse() {
65 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
68 clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}}
69 clang_analyzer_eval((void *)+getS() == (void *)&x); // expected-warning{{FALSE}}
70 clang_analyzer_eval((void *)-getS() == (void *)&x); // expected-warning{{FALSE}}
72 clang_analyzer_eval(getS().check()); // expected-warning{{TRUE}}
73 clang_analyzer_eval(!getS()); // expected-warning{{FALSE}}
74 clang_analyzer_eval(~getS()); // expected-warning{{FALSE}}
78 int getConstrainedField(struct S s) {
79 if (s.field != 42) return 42;
83 int getAssignedField(struct S s) {
89 clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
90 clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
93 void testImmediateUseParens() {
94 int x = ((getS())).field;
97 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
99 clang_analyzer_eval(getConstrainedField(((getS()))) == 42); // expected-warning{{TRUE}}
100 clang_analyzer_eval(getAssignedField(((getS()))) == 42); // expected-warning{{TRUE}}
103 clang_analyzer_eval(((getS())).check()); // expected-warning{{TRUE}}
104 clang_analyzer_eval(!((getS()))); // expected-warning{{FALSE}}
105 clang_analyzer_eval(~((getS()))); // expected-warning{{FALSE}}
110 //--------------------
112 //--------------------
115 void testReferenceAssignment() {
118 if (s.field != 42) return;
119 clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
121 clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
122 clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
124 clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
125 clang_analyzer_eval(!s); // expected-warning{{FALSE}}
126 clang_analyzer_eval(~s); // expected-warning{{FALSE}}
128 clang_analyzer_eval(*s == 42); // expected-warning{{TRUE}}
132 int getConstrainedFieldRef(const S &s) {
133 if (s.field != 42) return 42;
137 bool checkThis(const S &s) {
138 return s.getThis() == &s;
141 bool checkThisOp(const S &s) {
145 bool checkThisStaticOp(const S &s) {
149 void testReferenceArgument() {
150 clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
151 clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
152 clang_analyzer_eval(checkThisOp(getS())); // expected-warning{{TRUE}}
153 clang_analyzer_eval(checkThisStaticOp(getS())); // expected-warning{{TRUE}}
157 int getConstrainedFieldOp(S s) {
158 if (*s != 42) return 42;
162 int getConstrainedFieldRefOp(const S &s) {
163 if (*s != 42) return 42;
167 void testImmediateUseOp() {
170 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
172 clang_analyzer_eval(getConstrainedFieldOp(getS()) == 42); // expected-warning{{TRUE}}
173 clang_analyzer_eval(getConstrainedFieldRefOp(getS()) == 42); // expected-warning{{TRUE}}
176 namespace EmptyClass {
180 Base(int& x) : x(x) {}
183 struct Derived : public Base {
184 Derived(int& x) : Base(x) {}
186 void operator=(int a) { x = a; }
189 Derived ref(int& a) { return Derived(a); }
191 // There used to be a warning here, because analyzer treated Derived as empty.
195 return a; // no warning