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