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