misc-ps-region-store.cpp revision 892697dd2287caf7c29aaaa82909b0e90b8b63fe
1// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
2// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
3// XFAIL: *
4
5// Test basic handling of references.
6char &test1_aux();
7char *test1() {
8  return &test1_aux();
9}
10
11// Test test1_aux() evaluates to char &.
12char test1_as_rvalue() {
13  return test1_aux();
14}
15
16// Test passing a value as a reference.  The 'const' in test2_aux() adds
17// an ImplicitCastExpr, which is evaluated as an lvalue.
18int test2_aux(const int &n);
19int test2(int n) {
20  return test2_aux(n);
21}
22
23int test2_b_aux(const short &n);
24int test2_b(int n) {
25  return test2_b_aux(n);
26}
27
28// Test getting the lvalue of a derived and converting it to a base.  This
29// previously crashed.
30class Test3_Base {};
31class Test3_Derived : public Test3_Base {};
32
33int test3_aux(Test3_Base &x);
34int test3(Test3_Derived x) {
35  return test3_aux(x);
36}
37
38//===---------------------------------------------------------------------===//
39// Test CFG support for C++ condition variables.
40//===---------------------------------------------------------------------===//
41
42int test_init_in_condition_aux();
43int test_init_in_condition() {
44  if (int x = test_init_in_condition_aux()) { // no-warning
45    return 1;
46  }
47  return 0;
48}
49
50int test_init_in_condition_switch() {
51  switch (int x = test_init_in_condition_aux()) { // no-warning
52    case 1:
53      return 0;
54    case 2:
55      if (x == 2)
56        return 0;
57      else {
58        // Unreachable.
59        int *p = 0;
60        *p = 0xDEADBEEF; // no-warning
61      }
62    default:
63      break;
64  }
65  return 0;
66}
67
68int test_init_in_condition_while() {
69  int z = 0;
70  while (int x = ++z) { // no-warning
71    if (x == 2)
72      break;
73  }
74
75  if (z == 2)
76    return 0;
77
78  int *p = 0;
79  *p = 0xDEADBEEF; // no-warning
80  return 0;
81}
82
83
84int test_init_in_condition_for() {
85  int z = 0;
86  for (int x = 0; int y = ++z; ++x) {
87    if (x == y) // no-warning
88      break;
89  }
90  if (z == 1)
91    return 0;
92
93  int *p = 0;
94  *p = 0xDEADBEEF; // no-warning
95  return 0;
96}
97
98//===---------------------------------------------------------------------===//
99// Test handling of 'this' pointer.
100//===---------------------------------------------------------------------===//
101
102class TestHandleThis {
103  int x;
104
105  TestHandleThis();
106  int foo();
107  int null_deref_negative();
108  int null_deref_positive();
109};
110
111int TestHandleThis::foo() {
112  // Assume that 'x' is initialized.
113  return x + 1; // no-warning
114}
115
116int TestHandleThis::null_deref_negative() {
117  x = 10;
118  if (x == 10) {
119    return 1;
120  }
121  int *p = 0;
122  *p = 0xDEADBEEF; // no-warning
123  return 0;
124}
125
126int TestHandleThis::null_deref_positive() {
127  x = 10;
128  if (x == 9) {
129    return 1;
130  }
131  int *p = 0;
132  *p = 0xDEADBEEF; // expected-warning{{null pointer}}
133  return 0;
134}
135
136// PR 7675 - passing literals by-reference
137void pr7675(const double &a);
138void pr7675(const int &a);
139void pr7675(const char &a);
140void pr7675_i(const _Complex double &a);
141
142void pr7675_test() {
143  pr7675(10.0);
144  pr7675(10);
145  pr7675('c');
146  pr7675_i(4.0i);
147  // Add null deref to ensure we are analyzing the code up to this point.
148  int *p = 0;
149  *p = 0xDEADBEEF; // expected-warning{{null pointer}}
150}
151
152// <rdar://problem/8375510> - CFGBuilder should handle temporaries.
153struct R8375510 {
154  R8375510();
155  ~R8375510();
156  R8375510 operator++(int);
157};
158
159int r8375510(R8375510 x, R8375510 y) {
160  for (; ; x++) { }
161}
162
163// PR8419 -- this used to crash.
164
165class String8419 {
166 public:
167  char& get(int n);
168  char& operator[](int n);
169};
170
171char& get8419();
172
173void Test8419() {
174  String8419 s;
175  ++(s.get(0));
176  get8419()--;  // used to crash
177  --s[0];       // used to crash
178  s[0] &= 1;    // used to crash
179  s[0]++;       // used to crash
180}
181
182// PR8426 -- this used to crash.
183
184void Use(void* to);
185
186template <class T> class Foo {
187  ~Foo();
188  struct Bar;
189  Bar* bar_;
190};
191
192template <class T> Foo<T>::~Foo() {
193  Use(bar_);
194  T::DoSomething();
195  bar_->Work();
196}
197
198// PR8427 -- this used to crash.
199
200class Dummy {};
201
202bool operator==(Dummy, int);
203
204template <typename T>
205class Foo2 {
206  bool Bar();
207};
208
209template <typename T>
210bool Foo2<T>::Bar() {
211  return 0 == T();
212}
213
214// PR8433 -- this used to crash.
215
216template <typename T>
217class Foo3 {
218 public:
219  void Bar();
220  void Baz();
221  T value_;
222};
223
224template <typename T>
225void Foo3<T>::Bar() {
226  Baz();
227  value_();
228}
229