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