147 lines
5.2 KiB
C++
147 lines
5.2 KiB
C++
// 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
|