123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
- // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
- // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
- // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
- void clang_analyzer_eval(int);
- struct S {
- int field;
- #if __cplusplus
- const struct S *getThis() const { return this; }
- const struct S *operator +() const { return this; }
- bool check() const { return this == this; }
- bool operator !() const { return this != this; }
- int operator *() const { return field; }
- #endif
- };
- #if __cplusplus
- const struct S *operator -(const struct S &s) { return &s; }
- bool operator ~(const struct S &s) { return &s != &s; }
- #endif
- #ifdef INLINE
- struct S getS() {
- struct S s = { 42 };
- return s;
- }
- #else
- struct S getS();
- #endif
- void testAssignment() {
- struct S s = getS();
- if (s.field != 42) return;
- clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
- s.field = 0;
- clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}}
- #if __cplusplus
- clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
- clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
- clang_analyzer_eval(-s == &s); // expected-warning{{TRUE}}
- clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
- clang_analyzer_eval(!s); // expected-warning{{FALSE}}
- clang_analyzer_eval(~s); // expected-warning{{FALSE}}
- clang_analyzer_eval(*s == 0); // expected-warning{{TRUE}}
- #endif
- }
- void testImmediateUse() {
- int x = getS().field;
- if (x != 42) return;
- clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
- #if __cplusplus
- clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}}
- clang_analyzer_eval((void *)+getS() == (void *)&x); // expected-warning{{FALSE}}
- clang_analyzer_eval((void *)-getS() == (void *)&x); // expected-warning{{FALSE}}
- clang_analyzer_eval(getS().check()); // expected-warning{{TRUE}}
- clang_analyzer_eval(!getS()); // expected-warning{{FALSE}}
- clang_analyzer_eval(~getS()); // expected-warning{{FALSE}}
- #endif
- }
- int getConstrainedField(struct S s) {
- if (s.field != 42) return 42;
- return s.field;
- }
- int getAssignedField(struct S s) {
- s.field = 42;
- return s.field;
- }
- void testArgument() {
- clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
- clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
- }
- //--------------------
- // C++-only tests
- //--------------------
- #if __cplusplus
- void testReferenceAssignment() {
- const S &s = getS();
- if (s.field != 42) return;
- clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
- clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
- clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
- clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
- clang_analyzer_eval(!s); // expected-warning{{FALSE}}
- clang_analyzer_eval(~s); // expected-warning{{FALSE}}
- clang_analyzer_eval(*s == 42); // expected-warning{{TRUE}}
- }
- int getConstrainedFieldRef(const S &s) {
- if (s.field != 42) return 42;
- return s.field;
- }
- bool checkThis(const S &s) {
- return s.getThis() == &s;
- }
- bool checkThisOp(const S &s) {
- return +s == &s;
- }
- bool checkThisStaticOp(const S &s) {
- return -s == &s;
- }
- void testReferenceArgument() {
- clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
- clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
- clang_analyzer_eval(checkThisOp(getS())); // expected-warning{{TRUE}}
- clang_analyzer_eval(checkThisStaticOp(getS())); // expected-warning{{TRUE}}
- }
- int getConstrainedFieldOp(S s) {
- if (*s != 42) return 42;
- return *s;
- }
- int getConstrainedFieldRefOp(const S &s) {
- if (*s != 42) return 42;
- return *s;
- }
- void testImmediateUseOp() {
- int x = *getS();
- if (x != 42) return;
- clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
- clang_analyzer_eval(getConstrainedFieldOp(getS()) == 42); // expected-warning{{TRUE}}
- clang_analyzer_eval(getConstrainedFieldRefOp(getS()) == 42); // expected-warning{{TRUE}}
- }
- #endif
|