array-struct-region.cpp revision e885dd6a135a335422f33e5f1aa64b8d62c84255
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 4void clang_analyzer_eval(int); 5 6struct S { 7 int field; 8 9#if __cplusplus 10 const struct S *getThis() const { return this; } 11#endif 12}; 13 14struct S getS(); 15 16 17void 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 32void 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 43int getConstrainedField(struct S s) { 44 if (s.field != 42) return 42; 45 return s.field; 46} 47 48int getAssignedField(struct S s) { 49 s.field = 42; 50 return s.field; 51} 52 53void 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 70void 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 80int getConstrainedFieldRef(const S &s) { 81 if (s.field != 42) return 42; 82 return s.field; 83} 84 85bool checkThis(const S &s) { 86 return s.getThis() == &s; 87} 88 89void testReferenceArgument() { 90 clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}} 91 clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}} 92} 93#endif 94