blob: 37dc0fdaad935dbd794a7b9e4bb7446992c5dd24 [file] [log] [blame]
// 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();
}
}