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 8void 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} 12namespace MemberCheck { 13struct 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 28void 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 34S::S() 35: b(new int[1]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}} 36// expected-note@-1 {{allocated with 'new' here}} 37 38S::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 42struct 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}; 47int *S::d = new int[42]; // expected-note {{allocated with 'new[]' here}} 48void 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'. 59struct 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. 73struct CantProve_MissingCtorDefinition { 74 int *p; 75 CantProve_MissingCtorDefinition(); 76 CantProve_MissingCtorDefinition(int); 77 ~CantProve_MissingCtorDefinition(); 78}; 79 80CantProve_MissingCtorDefinition::CantProve_MissingCtorDefinition() 81 : p(new int) 82{ } 83 84CantProve_MissingCtorDefinition::~CantProve_MissingCtorDefinition() 85{ 86 delete[] p; 87} 88 89struct base {}; 90struct derived : base {}; 91struct 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 105namespace NonMemberCheck { 106#define DELETE_ARRAY(x) delete[] (x) 107#define DELETE(x) delete (x) 108void 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 124namespace MissingInitializer { 125template<typename T> 126struct Base { 127 struct S { 128 const T *p1 = nullptr; 129 const T *p2 = new T[3]; 130 }; 131}; 132 133void null_init(Base<double>::S s) { 134 delete s.p1; 135 delete s.p2; 136} 137} 138 139#ifndef WITH_PCH 140pch_test::X::X() 141 : a(new int[1]) // expected-note{{allocated with 'new[]' here}} 142{ } 143pch_test::X::X(int i) 144 : a(new int[i]) // expected-note{{allocated with 'new[]' here}} 145{ } 146#endif 147