1e449edc5bdace60f9d754c32abc5459bc7d94a14Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s 2176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -analyze -analyzer-checker=core,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 9033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar//----------------------------------------- 9133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar// check for usage of zero-allocated memory 9233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar//----------------------------------------- 9333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 9433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid testUseZeroAlloc1() { 9533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar int *p = (int *)operator new(0); 9633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar *p = 1; // expected-warning {{Use of zero-allocated memory}} 9733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar delete p; 9833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar} 9933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 10033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarint testUseZeroAlloc2() { 10133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar int *p = (int *)operator new[](0); 10233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return p[0]; // expected-warning {{Use of zero-allocated memory}} 10333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar delete[] p; 10433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar} 10533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 10633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid f(int); 10733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 10833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid testUseZeroAlloc3() { 10933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar int *p = new int[0]; 11033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar f(*p); // expected-warning {{Use of zero-allocated memory}} 11133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar delete[] p; 11233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar} 11333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 1142de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev//--------------- 1152de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev// other checks 1162de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev//--------------- 1172de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev 11855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevclass SomeClass { 11955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevpublic: 12055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev void f(int *p); 12155e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev}; 12255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev 12355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid f(int *p1, int *p2 = 0, int *p3 = 0); 12455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid g(SomeClass &c, ...); 1252de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev 12655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseFirstArgAfterDelete() { 1272de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev int *p = new int; 1282de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev delete p; 1292de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev f(p); // expected-warning{{Use of memory after it is freed}} 1302de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev} 1312de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev 13255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseMiddleArgAfterDelete(int *p) { 13355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev delete p; 13455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev f(0, p); // expected-warning{{Use of memory after it is freed}} 13555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev} 13655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev 13755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseLastArgAfterDelete(int *p) { 13855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev delete p; 13955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev f(0, 0, p); // expected-warning{{Use of memory after it is freed}} 14055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev} 14155e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev 142337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsevvoid testUseSeveralArgsAfterDelete(int *p) { 143337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev delete p; 144337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev f(p, p, p); // expected-warning{{Use of memory after it is freed}} 145337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev} 146337ad7627ca82b1bcba37618d40129c3e59be86bAnton Yartsev 14755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseRefArgAfterDelete(SomeClass &c) { 14855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev delete &c; 14955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev g(c); // expected-warning{{Use of memory after it is freed}} 15055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev} 15155e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev 15255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testVariadicArgAfterDelete() { 15355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev SomeClass c; 15455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev int *p = new int; 15555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev delete p; 15655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev g(c, 0, p); // expected-warning{{Use of memory after it is freed}} 15755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev} 15855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev 15955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseMethodArgAfterDelete(int *p) { 16055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev SomeClass *c = new SomeClass; 16155e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev delete p; 16255e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev c->f(p); // expected-warning{{Use of memory after it is freed}} 16355e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev} 16455e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev 16555e57a50a36749ce0483db2f16259649c9d25792Anton Yartsevvoid testUseThisAfterDelete() { 16655e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev SomeClass *c = new SomeClass; 16755e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev delete c; 16855e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev c->f(0); // expected-warning{{Use of memory after it is freed}} 16955e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev} 17055e57a50a36749ce0483db2f16259649c9d25792Anton Yartsev 1712de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testDoubleDelete() { 1722de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev int *p = new int; 1732de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev delete p; 1742de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev delete p; // expected-warning{{Attempt to free released memory}} 1752de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev} 1762de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev 1772de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testExprDeleteArg() { 1782de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev int i; 179849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}} 180849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev} 1812de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev 1822de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testExprDeleteArrArg() { 1832de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev int i; 184849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}} 185849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev} 1862de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev 1872de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsevvoid testAllocDeallocNames() { 1882de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev int *p = new(std::nothrow) int[1]; 189849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev delete[] (++p); // expected-warning{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}} 190849c7bf718ed3c08bd66b93f0bd508a44bb2f669Anton Yartsev} 1912de19edab6001d2c17720d02fe0760b9b452192aAnton Yartsev 19241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks//-------------------------------- 19341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks// Test escape of newed const pointer. Note, a const pointer can be deleted. 19441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks//-------------------------------- 19541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksstruct StWithConstPtr { 19641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks const int *memp; 19741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks}; 19841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escape(const int &x); 19941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escapeStruct(const StWithConstPtr &x); 20041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escapePtr(const StWithConstPtr *x); 20141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid escapeVoidPtr(const void *x); 20241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 20341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscape() { 20441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks int *p = new int(1); 20541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks escape(*p); 20641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning 20741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 20841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapeStruct() { 20941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks StWithConstPtr *St = new StWithConstPtr(); 21041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks escapeStruct(*St); 21141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning 21241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 21341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapeStructPtr() { 21441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks StWithConstPtr *St = new StWithConstPtr(); 21541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks escapePtr(St); 21641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning 21741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 21841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapeMember() { 21941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks StWithConstPtr St; 22041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks St.memp = new int(2); 22141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks escapeVoidPtr(St.memp); 22241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning 22341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 22441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid testConstEscapePlacementNew() { 22541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks int *x = (int *)malloc(sizeof(int)); 22641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks void *y = new (x) int; 22741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks escapeVoidPtr(y); 22841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks} // no-warning 22950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 230fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose//============== Test Uninitialized delete delete[]======================== 231fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDelete() { 232fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose int *x; 233fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose int * y = new int; 234fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose delete y; 235fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose delete x; // expected-warning{{Argument to 'delete' is uninitialized}} 236fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose} 237fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 238fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDeleteArray() { 239fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose int *x; 240fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose int * y = new int[5]; 241fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose delete[] y; 242fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}} 243fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose} 244fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 245fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitFree() { 246fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose int *x; 247fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose free(x); // expected-warning{{Function call argument is an uninitialized value}} 248fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose} 249fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 250fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDeleteSink() { 251fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose int *x; 252fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose delete x; // expected-warning{{Argument to 'delete' is uninitialized}} 253fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose (*(volatile int *)0 = 1); // no warn 254fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose} 255fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 256fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rosevoid testUninitDeleteArraySink() { 257fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose int *x; 258fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}} 259fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose (*(volatile int *)0 = 1); // no warn 260fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose} 26150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 26250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rosenamespace reference_count { 26350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose class control_block { 26450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose unsigned count; 26550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose public: 26650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose control_block() : count(0) {} 26750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void retain() { ++count; } 26850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose int release() { return --count; } 26950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose }; 27050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 27150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose template <typename T> 27250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose class shared_ptr { 27350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose T *p; 27450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose control_block *control; 27550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 27650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose public: 27750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr() : p(0), control(0) {} 27850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose explicit shared_ptr(T *p) : p(p), control(new control_block) { 27950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose control->retain(); 28050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 28150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr(shared_ptr &other) : p(other.p), control(other.control) { 28250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose if (control) 28350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose control->retain(); 28450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 28550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose ~shared_ptr() { 28650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose if (control && control->release() == 0) { 28750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose delete p; 28850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose delete control; 28950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 29050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose }; 29150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 29250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose T &operator *() { 29350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose return *p; 29450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose }; 29550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 29650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void swap(shared_ptr &other) { 29750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose T *tmp = p; 29850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose p = other.p; 29950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose other.p = tmp; 30050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 30150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose control_block *ctrlTmp = control; 30250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose control = other.control; 30350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose other.control = ctrlTmp; 30450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 30550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose }; 30650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 30750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void testSingle() { 30850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> a(new int); 30950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose *a = 1; 31050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 31150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 31250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void testDouble() { 31350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> a(new int); 31450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> b = a; 31550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose *a = 1; 31650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 31750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 31850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void testInvalidated() { 31950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> a(new int); 32050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> b = a; 32150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose *a = 1; 32250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 32350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose extern void use(shared_ptr<int> &); 32450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose use(b); 32550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 32650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 32750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void testNestedScope() { 32850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> a(new int); 32950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose { 33050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> b = a; 33150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 33250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose *a = 1; 33350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 33450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 33550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void testSwap() { 33650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> a(new int); 33750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> b; 33850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> c = a; 33950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int>(c).swap(b); 34050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 34150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 34250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose void testUseAfterFree() { 34350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose int *p = new int; 34450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose { 34550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> a(p); 34650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose shared_ptr<int> b = a; 34750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 34850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 34950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose // FIXME: We should get a warning here, but we don't because we've 35050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose // conservatively modeled ~shared_ptr. 35150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose *p = 1; 35250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose } 35350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose} 35450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose 35581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose// Test double delete 35681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Roseclass DerefClass{ 35781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosepublic: 35881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose int *x; 35981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose DerefClass() {} 360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ~DerefClass() {*x = 1;} 36181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose}; 36281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 36381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosevoid testDoubleDeleteClassInstance() { 36481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose DerefClass *foo = new DerefClass(); 36581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose delete foo; 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines delete foo; // expected-warning {{Attempt to delete released memory}} 36781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose} 36881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 36981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Roseclass EmptyClass{ 37081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosepublic: 37181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose EmptyClass() {} 37281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose ~EmptyClass() {} 37381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose}; 37481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 37581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rosevoid testDoubleDeleteEmptyClass() { 37681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose EmptyClass *foo = new EmptyClass(); 37781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose delete foo; 378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines delete foo; // expected-warning {{Attempt to delete released memory}} 37981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose} 380