1 // Test without PCH 2 // RUN: %clang_cc1 -fsyntax-only -include %S/delete-mismatch.h -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s 3 4 // Test with PCH 5 // RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/delete-mismatch.h 6 // RUN: %clang_cc1 -std=c++11 -include-pch %t -DWITH_PCH -fsyntax-only -verify %s -ast-dump 7 8 void f(int a[10][20]) { 9 delete a; // expected-warning {{'delete' applied to a pointer-to-array type}} 10 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]" 11 } 12 namespace MemberCheck { 13 struct S { 14 int *a = new int[5]; // expected-note4 {{allocated with 'new[]' here}} 15 int *b; 16 int *c; 17 static int *d; 18 S(); 19 S(int); 20 ~S() { 21 delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 22 delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 23 delete[] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} 24 } 25 void f(); 26 }; 27 28 void S::f() 29 { 30 delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 31 delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 32 } 33 34 S::S() 35 : b(new int[1]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}} 36 // expected-note@-1 {{allocated with 'new' here}} 37 38 S::S(int i) 39 : b(new int[i]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}} 40 // expected-note@-1 {{allocated with 'new' here}} 41 42 struct S2 : S { 43 ~S2() { 44 delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 45 } 46 }; 47 int *S::d = new int[42]; // expected-note {{allocated with 'new[]' here}} 48 void f(S *s) { 49 int *a = new int[1]; // expected-note {{allocated with 'new[]' here}} 50 delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 51 delete s->a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 52 delete s->b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 53 delete s->c; 54 delete s->d; 55 delete S::d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 56 } 57 58 // At least one constructor initializes field with matching form of 'new'. 59 struct MatchingNewIsOK { 60 int *p; 61 bool is_array_; 62 MatchingNewIsOK() : p{new int}, is_array_(false) {} 63 explicit MatchingNewIsOK(unsigned c) : p{new int[c]}, is_array_(true) {} 64 ~MatchingNewIsOK() { 65 if (is_array_) 66 delete[] p; 67 else 68 delete p; 69 } 70 }; 71 72 // At least one constructor's body is missing; no proof of mismatch. 73 struct CantProve_MissingCtorDefinition { 74 int *p; 75 CantProve_MissingCtorDefinition(); 76 CantProve_MissingCtorDefinition(int); 77 ~CantProve_MissingCtorDefinition(); 78 }; 79 80 CantProve_MissingCtorDefinition::CantProve_MissingCtorDefinition() 81 : p(new int) 82 { } 83 84 CantProve_MissingCtorDefinition::~CantProve_MissingCtorDefinition() 85 { 86 delete[] p; 87 } 88 89 struct base {}; 90 struct derived : base {}; 91 struct InitList { 92 base *p, *p2 = nullptr, *p3{nullptr}, *p4; 93 InitList(unsigned c) : p(new derived[c]), p4(nullptr) {} // expected-note {{allocated with 'new[]' here}} 94 InitList(unsigned c, unsigned) : p{new derived[c]}, p4{nullptr} {} // expected-note {{allocated with 'new[]' here}} 95 ~InitList() { 96 delete p; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 97 delete [] p; 98 delete p2; 99 delete [] p3; 100 delete p4; 101 } 102 }; 103 } 104 105 namespace NonMemberCheck { 106 #define DELETE_ARRAY(x) delete[] (x) 107 #define DELETE(x) delete (x) 108 void f() { 109 int *a = new int(5); // expected-note2 {{allocated with 'new' here}} 110 delete[] a; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} 111 int *b = new int; 112 delete b; 113 int *c{new int}; // expected-note {{allocated with 'new' here}} 114 int *d{new int[1]}; // expected-note2 {{allocated with 'new[]' here}} 115 delete [ ] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} 116 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:17}:"" 117 delete d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 118 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]" 119 DELETE_ARRAY(a); // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} 120 DELETE(d); // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} 121 } 122 } 123 124 namespace MissingInitializer { 125 template<typename T> 126 struct Base { 127 struct S { 128 const T *p1 = nullptr; 129 const T *p2 = new T[3]; 130 }; 131 }; 132 133 void null_init(Base<double>::S s) { 134 delete s.p1; 135 delete s.p2; 136 } 137 } 138 139 #ifndef WITH_PCH 140 pch_test::X::X() 141 : a(new int[1]) // expected-note{{allocated with 'new[]' here}} 142 { } 143 pch_test::X::X(int i) 144 : a(new int[i]) // expected-note{{allocated with 'new[]' here}} 145 { } 146 #endif 147