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 
f(int a[10][20])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);
~SMemberCheck::S20   ~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 
f()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 
S()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 
S(int i)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 {
~S2MemberCheck::S243   ~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}}
f(S * s)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_;
MatchingNewIsOKMemberCheck::MatchingNewIsOK62   MatchingNewIsOK() : p{new int}, is_array_(false) {}
MatchingNewIsOKMemberCheck::MatchingNewIsOK63   explicit MatchingNewIsOK(unsigned c) : p{new int[c]}, is_array_(true) {}
~MatchingNewIsOKMemberCheck::MatchingNewIsOK64   ~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 
CantProve_MissingCtorDefinition()80 CantProve_MissingCtorDefinition::CantProve_MissingCtorDefinition()
81   : p(new int)
82 { }
83 
~CantProve_MissingCtorDefinition()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;
InitListMemberCheck::InitList93   InitList(unsigned c) : p(new derived[c]), p4(nullptr) {}  // expected-note {{allocated with 'new[]' here}}
InitListMemberCheck::InitList94   InitList(unsigned c, unsigned) : p{new derived[c]}, p4{nullptr} {} // expected-note {{allocated with 'new[]' here}}
~InitListMemberCheck::InitList95   ~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)
f()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 
null_init(Base<double>::S s)133 void null_init(Base<double>::S s) {
134   delete s.p1;
135   delete s.p2;
136 }
137 }
138 
139 #ifndef WITH_PCH
X()140 pch_test::X::X()
141   : a(new int[1])  // expected-note{{allocated with 'new[]' here}}
142 { }
X(int i)143 pch_test::X::X(int i)
144   : a(new int[i])  // expected-note{{allocated with 'new[]' here}}
145 { }
146 #endif
147