array-struct-region.cpp revision f1e67d75fc922ff905de9faa6326bb1a96685ec1
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s 2// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s 3// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s 4// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s 5 6void clang_analyzer_eval(int); 7 8struct S { 9 int field; 10 11#if __cplusplus 12 const struct S *getThis() const { return this; } 13 const struct S *operator +() const { return this; } 14 15 bool check() const { return this == this; } 16 bool operator !() const { return this != this; } 17 18 int operator *() const { return field; } 19#endif 20}; 21 22#if __cplusplus 23const struct S *operator -(const struct S &s) { return &s; } 24bool operator ~(const struct S &s) { return &s != &s; } 25#endif 26 27 28#ifdef INLINE 29struct S getS() { 30 struct S s = { 42 }; 31 return s; 32} 33#else 34struct S getS(); 35#endif 36 37 38void testAssignment() { 39 struct S s = getS(); 40 41 if (s.field != 42) return; 42 clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}} 43 44 s.field = 0; 45 clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}} 46 47#if __cplusplus 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}} 51 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}} 55 56 clang_analyzer_eval(*s == 0); // expected-warning{{TRUE}} 57#endif 58} 59 60 61void testImmediateUse() { 62 int x = getS().field; 63 64 if (x != 42) return; 65 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} 66 67#if __cplusplus 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}} 71 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}} 75#endif 76} 77 78int getConstrainedField(struct S s) { 79 if (s.field != 42) return 42; 80 return s.field; 81} 82 83int getAssignedField(struct S s) { 84 s.field = 42; 85 return s.field; 86} 87 88void testArgument() { 89 clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}} 90 clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}} 91} 92 93 94//-------------------- 95// C++-only tests 96//-------------------- 97 98#if __cplusplus 99void testReferenceAssignment() { 100 const S &s = getS(); 101 102 if (s.field != 42) return; 103 clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}} 104 105 clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}} 106 clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}} 107 108 clang_analyzer_eval(s.check()); // expected-warning{{TRUE}} 109 clang_analyzer_eval(!s); // expected-warning{{FALSE}} 110 clang_analyzer_eval(~s); // expected-warning{{FALSE}} 111 112 clang_analyzer_eval(*s == 42); // expected-warning{{TRUE}} 113} 114 115 116int getConstrainedFieldRef(const S &s) { 117 if (s.field != 42) return 42; 118 return s.field; 119} 120 121bool checkThis(const S &s) { 122 return s.getThis() == &s; 123} 124 125bool checkThisOp(const S &s) { 126 return +s == &s; 127} 128 129bool checkThisStaticOp(const S &s) { 130 return -s == &s; 131} 132 133void testReferenceArgument() { 134 clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}} 135 clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}} 136 clang_analyzer_eval(checkThisOp(getS())); // expected-warning{{TRUE}} 137 clang_analyzer_eval(checkThisStaticOp(getS())); // expected-warning{{TRUE}} 138} 139 140 141int getConstrainedFieldOp(S s) { 142 if (*s != 42) return 42; 143 return *s; 144} 145 146int getConstrainedFieldRefOp(const S &s) { 147 if (*s != 42) return 42; 148 return *s; 149} 150 151void testImmediateUseOp() { 152 int x = *getS(); 153 if (x != 42) return; 154 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} 155 156 clang_analyzer_eval(getConstrainedFieldOp(getS()) == 42); // expected-warning{{TRUE}} 157 clang_analyzer_eval(getConstrainedFieldRefOp(getS()) == 42); // expected-warning{{TRUE}} 158} 159 160#endif 161