array-struct-region.cpp revision 0006ba445962621ed82ec84400a6b978205a3fbc
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#if __cplusplus 65 // FIXME: Passing the struct by value seems to be confusing C++. 66 // Possibly related to <rdar://problem/12137950>. 67 // expected-warning@-4{{UNKNOWN}} 68#endif 69 70 clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}} 71} 72 73 74//-------------------- 75// C++-only tests 76//-------------------- 77 78#if __cplusplus 79void testReferenceAssignment() { 80 const S &s = getS(); 81 82 if (s.field != 42) return; 83 clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}} 84 85 clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}} 86} 87 88 89int getConstrainedFieldRef(const S &s) { 90 if (s.field != 42) return 42; 91 return s.field; 92} 93 94bool checkThis(const S &s) { 95 return s.getThis() == &s; 96} 97 98void testReferenceArgument() { 99 clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}} 100 clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}} 101} 102#endif 103