new.cpp revision e6f2bf86288bc45060b21c4f55a6153b8ba80443
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s 2#include "Inputs/system-header-simulator-cxx.h" 3 4void clang_analyzer_eval(bool); 5 6typedef __typeof__(sizeof(int)) size_t; 7extern "C" void *malloc(size_t); 8extern "C" void free(void *); 9 10int someGlobal; 11void testImplicitlyDeclaredGlobalNew() { 12 if (someGlobal != 0) 13 return; 14 15 // This used to crash because the global operator new is being implicitly 16 // declared and it does not have a valid source location. (PR13090) 17 void *x = ::operator new(0); 18 ::operator delete(x); 19 20 // Check that the new/delete did not invalidate someGlobal; 21 clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} 22} 23 24void *testPlacementNew() { 25 int *x = (int *)malloc(sizeof(int)); 26 *x = 1; 27 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}}; 28 29 void *y = new (x) int; 30 clang_analyzer_eval(x == y); // expected-warning{{TRUE}}; 31 clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}}; 32 33 return y; 34} 35 36void *operator new(size_t, size_t, int *); 37void *testCustomNew() { 38 int x[1] = {1}; 39 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}}; 40 41 void *y = new (0, x) int; 42 clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}}; 43 44 return y; // no-warning 45} 46 47void *operator new(size_t, void *, void *); 48void *testCustomNewMalloc() { 49 int *x = (int *)malloc(sizeof(int)); 50 51 // Should be no-warning (the custom allocator could have freed x). 52 void *y = new (0, x) int; // no-warning 53 54 return y; 55} 56 57void testScalarInitialization() { 58 int *n = new int(3); 59 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} 60 61 new (n) int(); 62 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} 63 64 new (n) int{3}; 65 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} 66 67 new (n) int{}; 68 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} 69} 70 71struct PtrWrapper { 72 int *x; 73 74 PtrWrapper(int *input) : x(input) {} 75}; 76 77PtrWrapper *testNewInvalidation() { 78 // Ensure that we don't consider this a leak. 79 return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning 80} 81 82void testNewInvalidationPlacement(PtrWrapper *w) { 83 // Ensure that we don't consider this a leak. 84 new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning 85} 86 87int **testNewInvalidationScalar() { 88 // Ensure that we don't consider this a leak. 89 return new (int *)(static_cast<int *>(malloc(4))); // no-warning 90} 91 92void testNewInvalidationScalarPlacement(int **p) { 93 // Ensure that we don't consider this a leak. 94 new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning 95} 96 97void testCacheOut(PtrWrapper w) { 98 extern bool coin(); 99 if (coin()) 100 w.x = 0; 101 new (&w.x) (int*)(0); // we cache out here; don't crash 102} 103 104 105//-------------------------------------------------------------------- 106// Check for intersection with other checkers from MallocChecker.cpp 107// bounded with unix.Malloc 108//-------------------------------------------------------------------- 109 110// new/delete oparators are subjects of cplusplus.NewDelete. 111void testNewDeleteNoWarn() { 112 int i; 113 delete &i; // no-warning 114 115 int *p1 = new int; 116 delete ++p1; // no-warning 117 118 int *p2 = new int; 119 delete p2; 120 delete p2; // no-warning 121 122 int *p3 = new int; // no-warning 123} 124 125// unix.Malloc does not know about operators new/delete. 126void testDeleteMallocked() { 127 int *x = (int *)malloc(sizeof(int)); 128 delete x; // FIXME: Shoud detect pointer escape and keep silent after 'delete' is modeled properly. 129} // expected-warning{{Memory is never released; potential leak}} 130 131void testDeleteOpAfterFree() { 132 int *p = (int *)malloc(sizeof(int)); 133 free(p); 134 operator delete(p); // expected-warning{{Use of memory after it is freed}} 135} 136 137void testDeleteAfterFree() { 138 int *p = (int *)malloc(sizeof(int)); 139 free(p); 140 delete p; // expected-warning{{Use of memory after it is freed}} 141} 142 143void testStandardPlacementNewAfterFree() { 144 int *p = (int *)malloc(sizeof(int)); 145 free(p); 146 p = new(p) int; // expected-warning{{Use of memory after it is freed}} 147} 148 149void testCustomPlacementNewAfterFree() { 150 int *p = (int *)malloc(sizeof(int)); 151 free(p); 152 p = new(0, p) int; // expected-warning{{Use of memory after it is freed}} 153} 154 155//-------------------------------- 156// Incorrectly-modelled behavior 157//-------------------------------- 158 159int testNoInitialization() { 160 int *n = new int; 161 162 // Should warn that *n is uninitialized. 163 if (*n) { // no-warning 164 delete n; 165 return 0; 166 } 167 delete n; 168 return 1; 169} 170 171int testNoInitializationPlacement() { 172 int n; 173 new (&n) int; 174 175 // Should warn that n is uninitialized. 176 if (n) { // no-warning 177 return 0; 178 } 179 return 1; 180} 181