1e449edc5bdace60f9d754c32abc5459bc7d94a14Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
29df151c5bc2a746096632bbd21dc61e18675ed55Anton Yartsev// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
32de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev#include "Inputs/system-header-simulator-cxx.h"
42de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
52de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevtypedef __typeof__(sizeof(int)) size_t;
62de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevextern "C" void *malloc(size_t);
7fa220f58f02014e4a3389f429b82948a09dc4986Jordan Roseextern "C" void free (void* ptr);
82de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevint *global;
92de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
102de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev//------------------
112de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev// check for leaks
122de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev//------------------
132de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
14697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev//----- Standard non-placement operators
15697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testGlobalOpNew() {
16697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  void *p = operator new(0);
17e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose}
18e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#ifdef LEAKS
1968eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
20e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#endif
212de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
22697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testGlobalOpNewArray() {
23697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  void *p = operator new[](0);
24e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose}
25e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#ifdef LEAKS
2668eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
27e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#endif
282de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
29697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testGlobalNewExpr() {
302de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int *p = new int;
31e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose}
32e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#ifdef LEAKS
3368eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
34e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#endif
352de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
36697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testGlobalNewExprArray() {
37697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  int *p = new int[0];
38e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose}
39e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#ifdef LEAKS
4068eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
41e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#endif
422de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
43697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev//----- Standard nothrow placement operators
44697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testGlobalNoThrowPlacementOpNewBeforeOverload() {
45697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  void *p = operator new(0, std::nothrow);
46e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose}
47e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#ifdef LEAKS
4868eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
49e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#endif
502de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
51697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testGlobalNoThrowPlacementExprNewBeforeOverload() {
52697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  int *p = new(std::nothrow) int;
53e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose}
54e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#ifdef LEAKS
5568eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
56e85deb356f5d2d2172b7ef70314bc9cfc742a936Jordan Rose#endif
572de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
58697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev//----- Standard pointer placement operators
59697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testGlobalPointerPlacementNew() {
602de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int i;
612de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
62697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  void *p1 = operator new(0, &i); // no warn
632de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
64697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  void *p2 = operator new[](0, &i); // no warn
652de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
66697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  int *p3 = new(&i) int; // no warn
672de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
68697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  int *p4 = new(&i) int[0]; // no warn
692de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev}
702de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
71697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev//----- Other cases
72697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testNewMemoryIsInHeap() {
73697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  int *p = new int;
74697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  if (global != p) // condition is always true as 'p' wraps a heap region that
75697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev                   // is different from a region wrapped by 'global'
76697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev    global = p; // pointer escapes
772de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev}
782de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
79697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevstruct PtrWrapper {
80697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  int *x;
81697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev
82697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  PtrWrapper(int *input) : x(input) {}
83697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev};
842de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
85697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsevvoid testNewInvalidationPlacement(PtrWrapper *w) {
86697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  // Ensure that we don't consider this a leak.
87697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev  new (w) PtrWrapper(new int); // no warn
882de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev}
892de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
902de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev//---------------
912de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev// other checks
922de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev//---------------
932de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
9455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevclass SomeClass {
9555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevpublic:
9655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  void f(int *p);
9755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev};
9855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev
9955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid f(int *p1, int *p2 = 0, int *p3 = 0);
10055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid g(SomeClass &c, ...);
1012de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
10255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseFirstArgAfterDelete() {
1032de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int *p = new int;
1042de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  delete p;
1052de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  f(p); // expected-warning{{Use of memory after it is freed}}
1062de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev}
1072de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
10855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseMiddleArgAfterDelete(int *p) {
10955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  delete p;
11055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  f(0, p); // expected-warning{{Use of memory after it is freed}}
11155e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev}
11255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev
11355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseLastArgAfterDelete(int *p) {
11455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  delete p;
11555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  f(0, 0, p); // expected-warning{{Use of memory after it is freed}}
11655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev}
11755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev
118337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsevvoid testUseSeveralArgsAfterDelete(int *p) {
119337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev  delete p;
120337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev  f(p, p, p); // expected-warning{{Use of memory after it is freed}}
121337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev}
122337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev
12355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseRefArgAfterDelete(SomeClass &c) {
12455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  delete &c;
12555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  g(c); // expected-warning{{Use of memory after it is freed}}
12655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev}
12755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev
12855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testVariadicArgAfterDelete() {
12955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  SomeClass c;
13055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  int *p = new int;
13155e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  delete p;
13255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  g(c, 0, p); // expected-warning{{Use of memory after it is freed}}
13355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev}
13455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev
13555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseMethodArgAfterDelete(int *p) {
13655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  SomeClass *c = new SomeClass;
13755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  delete p;
13855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  c->f(p); // expected-warning{{Use of memory after it is freed}}
13955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev}
14055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev
14155e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseThisAfterDelete() {
14255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  SomeClass *c = new SomeClass;
14355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  delete c;
14455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev  c->f(0); // expected-warning{{Use of memory after it is freed}}
14555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev}
14655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev
1472de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testDeleteAlloca() {
1482de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int *p = (int *)__builtin_alloca(sizeof(int));
149849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev  delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
1502de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev}
1512de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
1522de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testDoubleDelete() {
1532de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int *p = new int;
1542de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  delete p;
1552de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  delete p; // expected-warning{{Attempt to free released memory}}
1562de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev}
1572de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
1582de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testExprDeleteArg() {
1592de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int i;
160849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev  delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
161849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev}
1622de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
1632de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testExprDeleteArrArg() {
1642de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int i;
165849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev  delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
166849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev}
1672de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
1682de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testAllocDeallocNames() {
1692de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev  int *p = new(std::nothrow) int[1];
170849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev  delete[] (++p); // expected-warning{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}}
171849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev}
1722de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev
17341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks//--------------------------------
17441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks// Test escape of newed const pointer. Note, a const pointer can be deleted.
17541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks//--------------------------------
17641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksstruct StWithConstPtr {
17741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  const int *memp;
17841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks};
17941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escape(const int &x);
18041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escapeStruct(const StWithConstPtr &x);
18141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escapePtr(const StWithConstPtr *x);
18241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escapeVoidPtr(const void *x);
18341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
18441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscape() {
18541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  int *p = new int(1);
18641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  escape(*p);
18741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning
18841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
18941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapeStruct() {
19041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  StWithConstPtr *St = new StWithConstPtr();
19141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  escapeStruct(*St);
19241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning
19341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
19441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapeStructPtr() {
19541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  StWithConstPtr *St = new StWithConstPtr();
19641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  escapePtr(St);
19741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning
19841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
19941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapeMember() {
20041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  StWithConstPtr St;
20141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  St.memp = new int(2);
20241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  escapeVoidPtr(St.memp);
20341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning
20441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
20541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapePlacementNew() {
20641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  int *x = (int *)malloc(sizeof(int));
20741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  void *y = new (x) int;
20841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  escapeVoidPtr(y);
20941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning
21050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
211fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose//============== Test Uninitialized delete delete[]========================
212fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDelete() {
213fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  int *x;
214fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  int * y = new int;
215fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  delete y;
216fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
217fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose}
218fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
219fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDeleteArray() {
220fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  int *x;
221fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  int * y = new int[5];
222fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  delete[] y;
223fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
224fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose}
225fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
226fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitFree() {
227fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  int *x;
228fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  free(x); // expected-warning{{Function call argument is an uninitialized value}}
229fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose}
230fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
231fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDeleteSink() {
232fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  int *x;
233fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
234fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  (*(volatile int *)0 = 1); // no warn
235fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose}
236fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
237fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDeleteArraySink() {
238fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  int *x;
239fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
240fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose  (*(volatile int *)0 = 1); // no warn
241fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose}
24250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
24350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rosenamespace reference_count {
24450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  class control_block {
24550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    unsigned count;
24650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  public:
24750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    control_block() : count(0) {}
24850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    void retain() { ++count; }
24950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    int release() { return --count; }
25050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  };
25150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
25250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  template <typename T>
25350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  class shared_ptr {
25450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    T *p;
25550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    control_block *control;
25650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
25750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  public:
25850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr() : p(0), control(0) {}
25950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    explicit shared_ptr(T *p) : p(p), control(new control_block) {
26050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      control->retain();
26150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    }
26250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr(shared_ptr &other) : p(other.p), control(other.control) {
26350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      if (control)
26450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose          control->retain();
26550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    }
26650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    ~shared_ptr() {
26750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      if (control && control->release() == 0) {
26850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose        delete p;
26950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose        delete control;
27050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      }
27150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    };
27250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
27350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    T &operator *() {
27450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      return *p;
27550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    };
27650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
27750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    void swap(shared_ptr &other) {
27850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      T *tmp = p;
27950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      p = other.p;
28050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      other.p = tmp;
28150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
28250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      control_block *ctrlTmp = control;
28350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      control = other.control;
28450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      other.control = ctrlTmp;
28550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    }
28650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  };
28750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
28850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  void testSingle() {
28950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> a(new int);
29050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    *a = 1;
29150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  }
29250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
29350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  void testDouble() {
29450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> a(new int);
29550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> b = a;
29650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    *a = 1;
29750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  }
29850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
29950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  void testInvalidated() {
30050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> a(new int);
30150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> b = a;
30250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    *a = 1;
30350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
30450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    extern void use(shared_ptr<int> &);
30550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    use(b);
30650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  }
30750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
30850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  void testNestedScope() {
30950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> a(new int);
31050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    {
31150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      shared_ptr<int> b = a;
31250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    }
31350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    *a = 1;
31450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  }
31550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
31650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  void testSwap() {
31750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> a(new int);
31850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> b;
31950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int> c = a;
32050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    shared_ptr<int>(c).swap(b);
32150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  }
32250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
32350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  void testUseAfterFree() {
32450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    int *p = new int;
32550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    {
32650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      shared_ptr<int> a(p);
32750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      shared_ptr<int> b = a;
32850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    }
32950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
33050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    // FIXME: We should get a warning here, but we don't because we've
33150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    // conservatively modeled ~shared_ptr.
33250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    *p = 1;
33350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  }
33450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose}
33550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
33681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose// Test double delete
33781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Roseclass DerefClass{
33881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosepublic:
33981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  int *x;
34081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  DerefClass() {}
341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ~DerefClass() {*x = 1;}
34281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose};
34381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose
34481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosevoid testDoubleDeleteClassInstance() {
34581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  DerefClass *foo = new DerefClass();
34681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  delete foo;
347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  delete foo; // expected-warning {{Attempt to delete released memory}}
34881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose}
34981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose
35081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Roseclass EmptyClass{
35181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosepublic:
35281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  EmptyClass() {}
35381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  ~EmptyClass() {}
35481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose};
35581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose
35681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosevoid testDoubleDeleteEmptyClass() {
35781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  EmptyClass *foo = new EmptyClass();
35881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose  delete foo;
359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  delete foo;  // expected-warning {{Attempt to delete released memory}}
36081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose}
361