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