dtor.cpp revision 1d3ca251f9891623fac0dbe70eece42564e274ed
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -cfg-add-initializers -Wno-null-dereference -verify %s 2 3void clang_analyzer_eval(bool); 4 5class A { 6public: 7 ~A() { 8 int *x = 0; 9 *x = 3; // expected-warning{{Dereference of null pointer}} 10 } 11}; 12 13int main() { 14 A a; 15} 16 17 18typedef __typeof(sizeof(int)) size_t; 19void *malloc(size_t); 20void free(void *); 21 22class SmartPointer { 23 void *X; 24public: 25 SmartPointer(void *x) : X(x) {} 26 ~SmartPointer() { 27 free(X); 28 } 29}; 30 31void testSmartPointer() { 32 char *mem = (char*)malloc(4); 33 { 34 SmartPointer Deleter(mem); 35 // destructor called here 36 } 37 *mem = 0; // expected-warning{{Use of memory after it is freed}} 38} 39 40 41void doSomething(); 42void testSmartPointer2() { 43 char *mem = (char*)malloc(4); 44 { 45 SmartPointer Deleter(mem); 46 // Remove dead bindings... 47 doSomething(); 48 // destructor called here 49 } 50 *mem = 0; // expected-warning{{Use of memory after it is freed}} 51} 52 53 54class Subclass : public SmartPointer { 55public: 56 Subclass(void *x) : SmartPointer(x) {} 57}; 58 59void testSubclassSmartPointer() { 60 char *mem = (char*)malloc(4); 61 { 62 Subclass Deleter(mem); 63 // Remove dead bindings... 64 doSomething(); 65 // destructor called here 66 } 67 *mem = 0; // expected-warning{{Use of memory after it is freed}} 68} 69 70 71class MultipleInheritance : public Subclass, public SmartPointer { 72public: 73 MultipleInheritance(void *a, void *b) : Subclass(a), SmartPointer(b) {} 74}; 75 76void testMultipleInheritance1() { 77 char *mem = (char*)malloc(4); 78 { 79 MultipleInheritance Deleter(mem, 0); 80 // Remove dead bindings... 81 doSomething(); 82 // destructor called here 83 } 84 *mem = 0; // expected-warning{{Use of memory after it is freed}} 85} 86 87void testMultipleInheritance2() { 88 char *mem = (char*)malloc(4); 89 { 90 MultipleInheritance Deleter(0, mem); 91 // Remove dead bindings... 92 doSomething(); 93 // destructor called here 94 } 95 *mem = 0; // expected-warning{{Use of memory after it is freed}} 96} 97 98void testMultipleInheritance3() { 99 char *mem = (char*)malloc(4); 100 { 101 MultipleInheritance Deleter(mem, mem); 102 // Remove dead bindings... 103 doSomething(); 104 // destructor called here 105 // expected-warning@27 {{Attempt to free released memory}} 106 } 107} 108 109 110class SmartPointerMember { 111 SmartPointer P; 112public: 113 SmartPointerMember(void *x) : P(x) {} 114}; 115 116void testSmartPointerMember() { 117 char *mem = (char*)malloc(4); 118 { 119 SmartPointerMember Deleter(mem); 120 // Remove dead bindings... 121 doSomething(); 122 // destructor called here 123 } 124 *mem = 0; // expected-warning{{Use of memory after it is freed}} 125} 126 127 128struct IntWrapper { 129 IntWrapper() : x(0) {} 130 ~IntWrapper(); 131 int *x; 132}; 133 134void testArrayInvalidation() { 135 int i = 42; 136 int j = 42; 137 138 { 139 IntWrapper arr[2]; 140 141 // There should be no undefined value warnings here. 142 // Eventually these should be TRUE as well, but right now 143 // we can't handle array constructors. 144 clang_analyzer_eval(arr[0].x == 0); // expected-warning{{UNKNOWN}} 145 clang_analyzer_eval(arr[1].x == 0); // expected-warning{{UNKNOWN}} 146 147 arr[0].x = &i; 148 arr[1].x = &j; 149 clang_analyzer_eval(*arr[0].x == 42); // expected-warning{{TRUE}} 150 clang_analyzer_eval(*arr[1].x == 42); // expected-warning{{TRUE}} 151 } 152 153 // The destructors should have invalidated i and j. 154 clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}} 155 clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}} 156} 157 158 159 160// Don't crash on a default argument inside an initializer. 161struct DefaultArg { 162 DefaultArg(int x = 0) {} 163 ~DefaultArg(); 164}; 165 166struct InheritsDefaultArg : DefaultArg { 167 InheritsDefaultArg() {} 168 virtual ~InheritsDefaultArg(); 169}; 170 171void testDefaultArg() { 172 InheritsDefaultArg a; 173 // Force a bug to be emitted. 174 *(char *)0 = 1; // expected-warning{{Dereference of null pointer}} 175} 176