new.cpp revision 2de19edab6001d2c17720d02fe0760b9b452192a
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))); 80} 81 82//-------------------------------------------------------------------- 83// Check for intersection with other checkers from MallocChecker.cpp 84// bounded with unix.Malloc 85//-------------------------------------------------------------------- 86 87// new/delete oparators are subjects of cplusplus.NewDelete. 88void testNewDeleteNoWarn() { 89 int i; 90 delete &i; // no-warning 91 92 int *p1 = new int; 93 delete ++p1; // no-warning 94 95 int *p2 = new int; 96 delete p2; 97 delete p2; // no-warning 98 99 int *p3 = new int; // no-warning 100} 101 102// unix.Malloc does not know about operators new/delete. 103void testDeleteMallocked() { 104 int *x = (int *)malloc(sizeof(int)); 105 delete x; // FIXME: Shoud detect pointer escape and keep silent after 'delete' is modeled properly. 106} // expected-warning{{Memory is never released; potential leak}} 107 108void testDeleteOpAfterFree() { 109 int *p = (int *)malloc(sizeof(int)); 110 free(p); 111 operator delete(p); // expected-warning{{Use of memory after it is freed}} 112} 113 114void testDeleteAfterFree() { 115 int *p = (int *)malloc(sizeof(int)); 116 free(p); 117 delete p; // expected-warning{{Use of memory after it is freed}} 118} 119 120void testStandardPlacementNewAfterFree() { 121 int *p = (int *)malloc(sizeof(int)); 122 free(p); 123 p = new(p) int; // expected-warning{{Use of memory after it is freed}} 124} 125 126void testCustomPlacementNewAfterFree() { 127 int *p = (int *)malloc(sizeof(int)); 128 free(p); 129 p = new(0, p) int; // expected-warning{{Use of memory after it is freed}} 130} 131 132//-------------------------------- 133// Incorrectly-modelled behavior 134//-------------------------------- 135 136int testNoInitialization() { 137 int *n = new int; 138 139 // Should warn that *n is uninitialized. 140 if (*n) { // no-warning 141 delete n; 142 return 0; 143 } 144 delete n; 145 return 1; 146} 147 148int testNoInitializationPlacement() { 149 int n; 150 new (&n) int; 151 152 // Should warn that n is uninitialized. 153 if (n) { // no-warning 154 return 0; 155 } 156 return 1; 157} 158