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