Skip to content

Commit 57e3019

Browse files
committed
Add cases where the addresses of the APIs in question are taken
1 parent 9d525db commit 57e3019

File tree

1 file changed

+173
-1
lines changed
  • cpp/misra/test/rules/RULE-21-6-2

1 file changed

+173
-1
lines changed

cpp/misra/test/rules/RULE-21-6-2/test.cpp

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include <cstdlib>
2+
#include <functional>
23
#include <memory>
34
#include <memory_resource>
5+
#include <new>
46
#include <scoped_allocator>
57
#include <stdlib.h>
68

@@ -14,7 +16,8 @@ class C1 {
1416
void use_of_new() {
1517
C1 x1; // COMPLIANT: no use of new
1618
C1 x2{}; // COMPLIANT: no use of new
17-
C1 *x3 = new C1; // NON_COMPLIANT: use of new
19+
C1 *x3 = new C1;
20+
// NON_COMPLIANT: use of new
1821
C1 *x4 = new (&x1) C1; // COMPLIANT: placement new (but violates Rule 21.6.3)
1922
}
2023

@@ -155,4 +158,173 @@ void delete_via_get() {
155158
delete raw; // NON_COMPLIANT: use of delete (causes double-free!)
156159
}
157160

161+
// Taking address of allocation functions (Item 2)
162+
163+
void take_address_of_malloc_etc() {
164+
std::function<void *(size_t)> alloc1 =
165+
std::malloc; // NON_COMPLIANT: implicit address-of malloc
166+
std::function<void *(size_t)> alloc2 =
167+
&std::malloc; // NON_COMPLIANT: explicit address-of malloc
168+
std::function<void *(size_t)> alloc3 =
169+
::malloc; // NON_COMPLIANT: implicit address-of malloc (global)
170+
std::function<void *(size_t)> alloc4 =
171+
&::malloc; // NON_COMPLIANT: explicit address-of malloc (global)
172+
173+
std::function<void *(size_t, size_t)> alloc5 =
174+
std::calloc; // NON_COMPLIANT: implicit address-of calloc
175+
std::function<void *(size_t, size_t)> alloc6 =
176+
&std::calloc; // NON_COMPLIANT: explicit address-of calloc
177+
178+
std::function<void *(void *, size_t)> alloc7 =
179+
std::realloc; // NON_COMPLIANT: implicit address-of realloc
180+
std::function<void *(void *, size_t)> alloc8 =
181+
&std::realloc; // NON_COMPLIANT: explicit address-of realloc
182+
183+
std::function<void *(size_t, size_t)> alloc9 =
184+
std::aligned_alloc; // NON_COMPLIANT: implicit address-of aligned_alloc
185+
std::function<void *(size_t, size_t)> alloc10 =
186+
&std::aligned_alloc; // NON_COMPLIANT: explicit address-of aligned_alloc
187+
188+
std::function<void(void *)> dealloc1 =
189+
std::free; // NON_COMPLIANT: implicit address-of free
190+
std::function<void(void *)> dealloc2 =
191+
&std::free; // NON_COMPLIANT: explicit address-of free
192+
std::function<void(void *)> dealloc3 =
193+
::free; // NON_COMPLIANT: implicit address-of free (global)
194+
std::function<void(void *)> dealloc4 =
195+
&::free; // NON_COMPLIANT: explicit address-of free (global)
196+
}
197+
198+
// Taking address of operator new/delete (Item 1)
199+
200+
void take_address_of_operator_new() {
201+
void *(*p1)(std::size_t) =
202+
&::operator new; // NON_COMPLIANT: address of operator new
203+
void *(*p2)(std::size_t) =
204+
::operator new; // NON_COMPLIANT: implicit address of operator new
205+
void *(*p3)(std::size_t) =
206+
&::operator new[]; // NON_COMPLIANT: address of operator new[]
207+
void *(*p4)(std::size_t) =
208+
::operator new[]; // NON_COMPLIANT: implicit address of operator new[]
209+
210+
void *(*p5)(std::size_t, const std::nothrow_t &) =
211+
&::operator new; // NON_COMPLIANT: address of nothrow operator new
212+
void *(*p6)(std::size_t, const std::nothrow_t &) =
213+
&::operator new[]; // NON_COMPLIANT: address of nothrow operator new[]
214+
}
215+
216+
void take_address_of_operator_delete() {
217+
void (*p1)(void *) =
218+
&::operator delete; // NON_COMPLIANT: address of operator delete
219+
void (*p2)(void *) =
220+
::operator delete; // NON_COMPLIANT: implicit address of operator delete
221+
void (*p3)(void *) =
222+
&::operator delete[]; // NON_COMPLIANT: address of operator delete[]
223+
void (*p4)(void *) =
224+
::operator delete[]; // NON_COMPLIANT: implicit address of operator
225+
// delete[]
226+
227+
void (*p5)(void *, const std::nothrow_t &) =
228+
&::operator delete; // NON_COMPLIANT: address of nothrow operator delete
229+
void (*p6)(void *, const std::nothrow_t &) =
230+
&::operator delete[]; // NON_COMPLIANT: address of nothrow operator
231+
// delete[]
232+
233+
void (*p7)(void *, std::size_t) =
234+
&::operator delete; // NON_COMPLIANT: address of sized operator delete
235+
void (*p8)(void *, std::size_t) =
236+
&::operator delete[]; // NON_COMPLIANT: address of sized operator
237+
// delete[]
238+
}
239+
240+
// Taking address of allocate/deallocate member functions (Item 3)
241+
242+
void take_address_of_allocate_deallocate() {
243+
// std::allocator
244+
auto p1 =
245+
&std::allocator<C1>::allocate; // NON_COMPLIANT: address of
246+
// std::allocator::allocate
247+
auto p2 =
248+
&std::allocator<C1>::deallocate; // NON_COMPLIANT: address of
249+
// std::allocator::deallocate
250+
251+
// std::allocator_traits (static member functions)
252+
auto p3 =
253+
&std::allocator_traits<
254+
std::allocator<C1>>::allocate; // NON_COMPLIANT: address of
255+
// std::allocator_traits::allocate
256+
auto p4 =
257+
&std::allocator_traits<
258+
std::allocator<C1>>::deallocate; // NON_COMPLIANT: address of
259+
// std::allocator_traits::deallocate
260+
261+
// std::pmr::memory_resource
262+
auto p5 =
263+
&std::pmr::memory_resource::allocate; // NON_COMPLIANT: address of
264+
// memory_resource::allocate
265+
auto p6 =
266+
&std::pmr::memory_resource::deallocate; // NON_COMPLIANT: address of
267+
// memory_resource::deallocate
268+
269+
// std::pmr::polymorphic_allocator
270+
auto p7 =
271+
&std::pmr::polymorphic_allocator<
272+
C1>::allocate; // NON_COMPLIANT: address of
273+
// polymorphic_allocator::allocate
274+
auto p8 =
275+
&std::pmr::polymorphic_allocator<
276+
C1>::deallocate; // NON_COMPLIANT: address of
277+
// polymorphic_allocator::deallocate
278+
279+
// std::pmr::monotonic_buffer_resource
280+
auto p9 =
281+
&std::pmr::monotonic_buffer_resource::
282+
allocate; // NON_COMPLIANT: address of
283+
// monotonic_buffer_resource::allocate
284+
auto p10 =
285+
&std::pmr::monotonic_buffer_resource::
286+
deallocate; // NON_COMPLIANT: address of
287+
// monotonic_buffer_resource::deallocate
288+
289+
// std::pmr::unsynchronized_pool_resource
290+
auto p11 =
291+
&std::pmr::unsynchronized_pool_resource::
292+
allocate; // NON_COMPLIANT: address of
293+
// unsynchronized_pool_resource::allocate
294+
auto p12 =
295+
&std::pmr::unsynchronized_pool_resource::
296+
deallocate; // NON_COMPLIANT: address of
297+
// unsynchronized_pool_resource::deallocate
298+
299+
// std::pmr::synchronized_pool_resource
300+
auto p13 =
301+
&std::pmr::synchronized_pool_resource::
302+
allocate; // NON_COMPLIANT: address of
303+
// synchronized_pool_resource::allocate
304+
auto p14 =
305+
&std::pmr::synchronized_pool_resource::
306+
deallocate; // NON_COMPLIANT: address of
307+
// synchronized_pool_resource::deallocate
308+
309+
// std::scoped_allocator_adaptor
310+
using ScopedAlloc = std::scoped_allocator_adaptor<std::allocator<C1>>;
311+
auto p15 =
312+
&ScopedAlloc::allocate; // NON_COMPLIANT: address of
313+
// scoped_allocator_adaptor::allocate
314+
auto p16 =
315+
&ScopedAlloc::deallocate; // NON_COMPLIANT: address of
316+
// scoped_allocator_adaptor::deallocate
317+
}
318+
319+
// Taking address of std::unique_ptr::release (Item 4)
320+
321+
void take_address_of_unique_ptr_release() {
322+
auto p1 =
323+
&std::unique_ptr<C1>::release; // NON_COMPLIANT: address of
324+
// std::unique_ptr::release
325+
auto p2 =
326+
&std::unique_ptr<C1[]>::release; // NON_COMPLIANT: address of
327+
// std::unique_ptr::release (array form)
328+
}
329+
158330
int main() { return 0; }

0 commit comments

Comments
 (0)