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