diff options
author | Ismail Pazarbasi <ismail.pazarbasi@gmail.com> | 2015-05-14 16:14:57 +0000 |
---|---|---|
committer | Ismail Pazarbasi <ismail.pazarbasi@gmail.com> | 2015-05-14 16:14:57 +0000 |
commit | 538ef53c139d9915327960217e922b2be7e8b3fd (patch) | |
tree | 3d6a10da310f704215fff7d5b0b3cbec701f3545 /clang/test/SemaCXX/delete.cpp | |
parent | 9d08232e28f6bbdfeb080d2d9f138a6dc55d7e93 (diff) | |
download | bcm5719-llvm-538ef53c139d9915327960217e922b2be7e8b3fd.tar.gz bcm5719-llvm-538ef53c139d9915327960217e922b2be7e8b3fd.zip |
Detect uses of mismatching forms of 'new' and 'delete'
Emit warning when operand to `delete` is allocated with `new[]` or
operand to `delete[]` is allocated with `new`.
Reviewers: rtrieu, jordan_rose, rsmith
Subscribers: majnemer, cfe-commits
Differential Revision: http://reviews.llvm.org/D4661
llvm-svn: 237368
Diffstat (limited to 'clang/test/SemaCXX/delete.cpp')
-rw-r--r-- | clang/test/SemaCXX/delete.cpp | 130 |
1 files changed, 125 insertions, 5 deletions
diff --git a/clang/test/SemaCXX/delete.cpp b/clang/test/SemaCXX/delete.cpp index 5824facc507..f808100a558 100644 --- a/clang/test/SemaCXX/delete.cpp +++ b/clang/test/SemaCXX/delete.cpp @@ -1,9 +1,129 @@ -// 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; + InitList() : p{new derived[1]} {} // expected-note {{allocated with 'new[]' here}} + explicit InitList(unsigned c) : p(new derived[c]) {} // expected-note {{allocated with 'new[]' here}} + InitList(unsigned c, unsigned) : p{new derived[c]} {} // expected-note {{allocated with 'new[]' here}} + InitList(const char *) : p{new derived[1]} {} // 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; + } +}; +} + +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 |