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 6 void clang_analyzer_eval(int); 7 8 struct S { 9 int field; 10 11 #if __cplusplus 12 const struct S *getThis() const { return this; } 13 #endif 14 }; 15 16 #ifdef INLINE 17 struct S getS() { 18 struct S s = { 42 }; 19 return s; 20 } 21 #else 22 struct S getS(); 23 #endif 24 25 26 void testAssignment() { 27 struct S s = getS(); 28 29 if (s.field != 42) return; 30 clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}} 31 32 s.field = 0; 33 clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}} 34 35 #if __cplusplus 36 clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}} 37 #endif 38 } 39 40 41 void testImmediateUse() { 42 int x = getS().field; 43 44 if (x != 42) return; 45 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} 46 47 #if __cplusplus 48 clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}} 49 #endif 50 } 51 52 int getConstrainedField(struct S s) { 53 if (s.field != 42) return 42; 54 return s.field; 55 } 56 57 int getAssignedField(struct S s) { 58 s.field = 42; 59 return s.field; 60 } 61 62 void testArgument() { 63 clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}} 64 clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}} 65 } 66 67 68 //-------------------- 69 // C++-only tests 70 //-------------------- 71 72 #if __cplusplus 73 void testReferenceAssignment() { 74 const S &s = getS(); 75 76 if (s.field != 42) return; 77 clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}} 78 79 clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}} 80 } 81 82 83 int getConstrainedFieldRef(const S &s) { 84 if (s.field != 42) return 42; 85 return s.field; 86 } 87 88 bool checkThis(const S &s) { 89 return s.getThis() == &s; 90 } 91 92 void testReferenceArgument() { 93 clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}} 94 clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}} 95 } 96 #endif 97