|  | // Test without PCH | 
|  | // RUN: %clang_cc1 -fsyntax-only -include %S/delete-mismatch.h -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s | 
|  |  | 
|  | // Test with PCH | 
|  | // RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/delete-mismatch.h | 
|  | // RUN: %clang_cc1 -std=c++11 -include-pch %t -DWITH_PCH -fsyntax-only -verify %s -ast-dump | 
|  |  | 
|  | void f(int a[10][20]) { | 
|  | delete a; // expected-warning {{'delete' applied to a pointer-to-array type}} | 
|  | // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]" | 
|  | } | 
|  | namespace MemberCheck { | 
|  | struct S { | 
|  | int *a = new int[5]; // expected-note4 {{allocated with 'new[]' here}} | 
|  | int *b; | 
|  | int *c; | 
|  | static int *d; | 
|  | S(); | 
|  | S(int); | 
|  | ~S() { | 
|  | delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | delete b;   // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | delete[] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} | 
|  | } | 
|  | void f(); | 
|  | }; | 
|  |  | 
|  | void S::f() | 
|  | { | 
|  | delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | } | 
|  |  | 
|  | S::S() | 
|  | : b(new int[1]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}} | 
|  | // expected-note@-1 {{allocated with 'new' here}} | 
|  |  | 
|  | S::S(int i) | 
|  | : b(new int[i]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}} | 
|  | // expected-note@-1 {{allocated with 'new' here}} | 
|  |  | 
|  | struct S2 : S { | 
|  | ~S2() { | 
|  | delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | } | 
|  | }; | 
|  | int *S::d = new int[42]; // expected-note {{allocated with 'new[]' here}} | 
|  | void f(S *s) { | 
|  | int *a = new int[1]; // expected-note {{allocated with 'new[]' here}} | 
|  | delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | delete s->a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | delete s->b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | delete s->c; | 
|  | delete s->d; | 
|  | delete S::d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | } | 
|  |  | 
|  | // At least one constructor initializes field with matching form of 'new'. | 
|  | struct MatchingNewIsOK { | 
|  | int *p; | 
|  | bool is_array_; | 
|  | MatchingNewIsOK() : p{new int}, is_array_(false) {} | 
|  | explicit MatchingNewIsOK(unsigned c) : p{new int[c]}, is_array_(true) {} | 
|  | ~MatchingNewIsOK() { | 
|  | if (is_array_) | 
|  | delete[] p; | 
|  | else | 
|  | delete p; | 
|  | } | 
|  | }; | 
|  |  | 
|  | // At least one constructor's body is missing; no proof of mismatch. | 
|  | struct CantProve_MissingCtorDefinition { | 
|  | int *p; | 
|  | CantProve_MissingCtorDefinition(); | 
|  | CantProve_MissingCtorDefinition(int); | 
|  | ~CantProve_MissingCtorDefinition(); | 
|  | }; | 
|  |  | 
|  | CantProve_MissingCtorDefinition::CantProve_MissingCtorDefinition() | 
|  | : p(new int) | 
|  | { } | 
|  |  | 
|  | CantProve_MissingCtorDefinition::~CantProve_MissingCtorDefinition() | 
|  | { | 
|  | delete[] p; | 
|  | } | 
|  |  | 
|  | struct base {}; | 
|  | struct derived : base {}; | 
|  | struct InitList { | 
|  | base *p, *p2 = nullptr, *p3{nullptr}, *p4; | 
|  | InitList(unsigned c) : p(new derived[c]), p4(nullptr) {}  // expected-note {{allocated with 'new[]' here}} | 
|  | InitList(unsigned c, unsigned) : p{new derived[c]}, p4{nullptr} {} // expected-note {{allocated with 'new[]' here}} | 
|  | ~InitList() { | 
|  | delete p; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | delete [] p; | 
|  | delete p2; | 
|  | delete [] p3; | 
|  | delete p4; | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | namespace NonMemberCheck { | 
|  | #define DELETE_ARRAY(x) delete[] (x) | 
|  | #define DELETE(x) delete (x) | 
|  | void f() { | 
|  | int *a = new int(5); // expected-note2 {{allocated with 'new' here}} | 
|  | delete[] a;          // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} | 
|  | int *b = new int; | 
|  | delete b; | 
|  | int *c{new int};    // expected-note {{allocated with 'new' here}} | 
|  | int *d{new int[1]}; // expected-note2 {{allocated with 'new[]' here}} | 
|  | delete  [    ] c;   // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} | 
|  | // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:17}:"" | 
|  | delete d;           // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]" | 
|  | DELETE_ARRAY(a);    // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} | 
|  | DELETE(d);          // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}} | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace MissingInitializer { | 
|  | template<typename T> | 
|  | struct Base { | 
|  | struct S { | 
|  | const T *p1 = nullptr; | 
|  | const T *p2 = new T[3]; | 
|  | }; | 
|  | }; | 
|  |  | 
|  | void null_init(Base<double>::S s) { | 
|  | delete s.p1; | 
|  | delete s.p2; | 
|  | } | 
|  | } | 
|  |  | 
|  | #ifndef WITH_PCH | 
|  | pch_test::X::X() | 
|  | : a(new int[1])  // expected-note{{allocated with 'new[]' here}} | 
|  | { } | 
|  | pch_test::X::X(int i) | 
|  | : a(new int[i])  // expected-note{{allocated with 'new[]' here}} | 
|  | { } | 
|  | #endif |