array-struct-region.cpp revision 580cd17f256259f39a382e967173f34d68e73859
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#endif 14}; 15 16#ifdef INLINE 17struct S getS() { 18 struct S s = { 42 }; 19 return s; 20} 21#else 22struct S getS(); 23#endif 24 25 26void 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 41void 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 52int getConstrainedField(struct S s) { 53 if (s.field != 42) return 42; 54 return s.field; 55} 56 57int getAssignedField(struct S s) { 58 s.field = 42; 59 return s.field; 60} 61 62void 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 73void 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 83int getConstrainedFieldRef(const S &s) { 84 if (s.field != 42) return 42; 85 return s.field; 86} 87 88bool checkThis(const S &s) { 89 return s.getThis() == &s; 90} 91 92void testReferenceArgument() { 93 clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}} 94 clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}} 95} 96#endif 97