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