summaryrefslogtreecommitdiff
path: root/test/SemaCXX/delete.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/delete.cpp')
-rw-r--r--test/SemaCXX/delete.cpp131
1 files changed, 126 insertions, 5 deletions
diff --git a/test/SemaCXX/delete.cpp b/test/SemaCXX/delete.cpp
index 5824facc507b..f94a8631613e 100644
--- a/test/SemaCXX/delete.cpp
+++ b/test/SemaCXX/delete.cpp
@@ -1,9 +1,130 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: cp %s %t
-// RUN: %clang_cc1 -fixit -x c++ %t
-// RUN: %clang_cc1 -E -o - %t | FileCheck %s
+// 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]) {
- // CHECK: delete[] a;
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[]'?}}
+}
}
+#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