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 | |