16ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
26ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
3f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
4f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
56ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
66ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosevoid clang_analyzer_eval(int);
76ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
86ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosestruct S {
96ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  int field;
106ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
116ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#if __cplusplus
126ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  const struct S *getThis() const { return this; }
13f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  const struct S *operator +() const { return this; }
14f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
15f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  bool check() const { return this == this; }
16f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  bool operator !() const { return this != this; }
17f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
18f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  int operator *() const { return field; }
196ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#endif
206ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose};
216ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
22f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose#if __cplusplus
23f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Roseconst struct S *operator -(const struct S &s) { return &s; }
249a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rosebool operator ~(const struct S &s) { return (&s) != &s; }
25f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose#endif
26f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
27f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
28f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose#ifdef INLINE
29f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rosestruct S getS() {
30f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  struct S s = { 42 };
31f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  return s;
32f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose}
33f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose#else
346ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosestruct S getS();
35f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose#endif
366ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
376ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
386ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosevoid testAssignment() {
396ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  struct S s = getS();
406ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
416ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  if (s.field != 42) return;
426ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
436ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
446ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  s.field = 0;
456ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}}
466ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
476ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#if __cplusplus
486ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
49f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
50f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(-s == &s); // expected-warning{{TRUE}}
51f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
52f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
53f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(!s); // expected-warning{{FALSE}}
54f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(~s); // expected-warning{{FALSE}}
55f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
56f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(*s == 0); // expected-warning{{TRUE}}
576ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#endif
586ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
596ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
606ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
616ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosevoid testImmediateUse() {
626ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  int x = getS().field;
636ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
646ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  if (x != 42) return;
656ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
666ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
676ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#if __cplusplus
686ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}}
69f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval((void *)+getS() == (void *)&x); // expected-warning{{FALSE}}
70f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval((void *)-getS() == (void *)&x); // expected-warning{{FALSE}}
71f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
72f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(getS().check()); // expected-warning{{TRUE}}
73f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(!getS()); // expected-warning{{FALSE}}
74f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(~getS()); // expected-warning{{FALSE}}
756ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#endif
766ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
776ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
786ebea89be233eaba5e29de8cf3524ad150c860bbJordan Roseint getConstrainedField(struct S s) {
796ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  if (s.field != 42) return 42;
806ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  return s.field;
816ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
826ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
836ebea89be233eaba5e29de8cf3524ad150c860bbJordan Roseint getAssignedField(struct S s) {
846ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  s.field = 42;
856ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  return s.field;
866ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
876ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
886ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosevoid testArgument() {
896ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
906ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
916ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
926ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
93d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rosevoid testImmediateUseParens() {
94d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  int x = ((getS())).field;
95d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose
96d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  if (x != 42) return;
97d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
98d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose
99d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  clang_analyzer_eval(getConstrainedField(((getS()))) == 42); // expected-warning{{TRUE}}
100d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  clang_analyzer_eval(getAssignedField(((getS()))) == 42); // expected-warning{{TRUE}}
101d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose
102d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose#if __cplusplus
103d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  clang_analyzer_eval(((getS())).check()); // expected-warning{{TRUE}}
104d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  clang_analyzer_eval(!((getS()))); // expected-warning{{FALSE}}
105d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose  clang_analyzer_eval(~((getS()))); // expected-warning{{FALSE}}
106d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose#endif
107d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose}
108d4ce811ae08398e357c8ce3e707ba5f2aa0041a5Jordan Rose
1096ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
1106ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose//--------------------
1116ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose// C++-only tests
1126ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose//--------------------
1136ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
1146ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#if __cplusplus
1156ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosevoid testReferenceAssignment() {
1166ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  const S &s = getS();
1176ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
1186ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  if (s.field != 42) return;
1196ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
1206ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
1216ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
122f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
123f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
124f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
125f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(!s); // expected-warning{{FALSE}}
126f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(~s); // expected-warning{{FALSE}}
127f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
128f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(*s == 42); // expected-warning{{TRUE}}
1296ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
1306ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
1316ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
1326ebea89be233eaba5e29de8cf3524ad150c860bbJordan Roseint getConstrainedFieldRef(const S &s) {
1336ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  if (s.field != 42) return 42;
1346ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  return s.field;
1356ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
1366ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
1376ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosebool checkThis(const S &s) {
1386ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  return s.getThis() == &s;
1396ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
1406ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose
141f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rosebool checkThisOp(const S &s) {
142f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  return +s == &s;
143f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose}
144f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
145f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rosebool checkThisStaticOp(const S &s) {
146f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  return -s == &s;
147f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose}
148f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
1496ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rosevoid testReferenceArgument() {
1506ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
1516ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose  clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
152f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(checkThisOp(getS())); // expected-warning{{TRUE}}
153f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(checkThisStaticOp(getS())); // expected-warning{{TRUE}}
154f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose}
155f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
156f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
157f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Roseint getConstrainedFieldOp(S s) {
158f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  if (*s != 42) return 42;
159f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  return *s;
160f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose}
161f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
162f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Roseint getConstrainedFieldRefOp(const S &s) {
163f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  if (*s != 42) return 42;
164f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  return *s;
1656ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose}
166f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
167f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rosevoid testImmediateUseOp() {
168f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  int x = *getS();
169f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  if (x != 42) return;
170f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
171f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
172f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(getConstrainedFieldOp(getS()) == 42); // expected-warning{{TRUE}}
173f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  clang_analyzer_eval(getConstrainedFieldRefOp(getS()) == 42); // expected-warning{{TRUE}}
174f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose}
175f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
1763c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labathnamespace EmptyClass {
1773c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  struct Base {
1783c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath    int& x;
1793c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath
1803c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath    Base(int& x) : x(x) {}
1813c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  };
1823c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath
1833c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  struct Derived : public Base {
1843c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath    Derived(int& x) : Base(x) {}
1853c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath
1863c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath    void operator=(int a) { x = a; }
1873c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  };
1883c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath
1893c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  Derived ref(int& a) { return Derived(a); }
1903c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath
1913c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  // There used to be a warning here, because analyzer treated Derived as empty.
1923c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  int test() {
1933c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath    int a;
1943c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath    ref(a) = 42;
1953c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath    return a; // no warning
1963c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath  }
1973c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath}
1983c114f704a882f6923d6107f22aab89ba3d0a6b5Pavel Labath
1996ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose#endif
200