1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
// RUN: %clang_cc1 -Wfree-nonheap-object -std=c++11 -x c++ -fsyntax-only -verify %s
extern "C" void free(void *) {}
namespace std {
using size_t = decltype(sizeof(0));
void *malloc(size_t);
void free(void *p);
} // namespace std
int GI;
void free_reference(char &x) { ::free(&x); }
void free_reference(char &&x) { ::free(&x); }
void std_free_reference(char &x) { std::free(&x); }
void std_free_reference(char &&x) { std::free(&x); }
struct S {
operator char *() { return ptr1; }
void CFree() {
::free(&ptr1); // expected-warning {{attempt to call free on non-heap object 'ptr1'}}
::free(&I); // expected-warning {{attempt to call free on non-heap object 'I'}}
::free(ptr1);
free_reference(*ptr2);
free_reference(static_cast<char&&>(*ptr3));
}
void CXXFree() {
std::free(&ptr1); // expected-warning {{attempt to call std::free on non-heap object 'ptr1'}}
std::free(&I); // expected-warning {{attempt to call std::free on non-heap object 'I'}}
std::free(ptr1);
std_free_reference(*ptr2);
std_free_reference(static_cast<char&&>(*ptr3));
}
private:
char *ptr1 = (char *)std::malloc(10);
char *ptr2 = (char *)std::malloc(10);
char *ptr3 = (char *)std::malloc(10);
static int I;
};
int S::I = 0;
void test1() {
{
free(&GI); // expected-warning {{attempt to call free on non-heap object 'GI'}}
}
{
static int SI = 0;
free(&SI); // expected-warning {{attempt to call free on non-heap object 'SI'}}
}
{
int I = 0;
free(&I); // expected-warning {{attempt to call free on non-heap object 'I'}}
}
{
int I = 0;
int *P = &I;
free(P);
}
{
void *P = std::malloc(8);
free(P); // FIXME diagnosing this would require control flow analysis.
}
{
int A[] = {0, 1, 2, 3};
free(A); // expected-warning {{attempt to call free on non-heap object 'A'}}
}
{
int A[] = {0, 1, 2, 3};
free(&A); // expected-warning {{attempt to call free on non-heap object 'A'}}
}
{
S s;
free(s);
free(&s); // expected-warning {{attempt to call free on non-heap object 's'}}
}
{
S s;
s.CFree();
}
}
void test2() {
{
std::free(&GI); // expected-warning {{attempt to call std::free on non-heap object 'GI'}}
}
{
static int SI = 0;
std::free(&SI); // expected-warning {{attempt to call std::free on non-heap object 'SI'}}
}
{
int I = 0;
std::free(&I); // expected-warning {{attempt to call std::free on non-heap object 'I'}}
}
{
int I = 0;
int *P = &I;
std::free(P); // FIXME diagnosing this would require control flow analysis.
}
{
void *P = std::malloc(8);
std::free(P);
}
{
char* P = (char *)std::malloc(2);
std_free_reference(*P);
}
{
char* P = (char *)std::malloc(2);
std_free_reference(static_cast<char&&>(*P));
}
{
int A[] = {0, 1, 2, 3};
std::free(A); // expected-warning {{attempt to call std::free on non-heap object 'A'}}
}
{
int A[] = {0, 1, 2, 3};
std::free(&A); // expected-warning {{attempt to call std::free on non-heap object 'A'}}
}
{
S s;
std::free(s);
std::free(&s); // expected-warning {{attempt to call std::free on non-heap object 's'}}
}
{
S s;
s.CXXFree();
}
}
|