From: Siddhesh Poyarekar Date: Wed, 28 Jul 2021 05:03:46 +0000 (+0530) Subject: analyzer: Recognize __builtin_free as a matching deallocator X-Git-Tag: upstream/12.2.0~6131 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84606efb0c6b1c1598d5ec6b05544e71596663b5;p=platform%2Fupstream%2Fgcc.git analyzer: Recognize __builtin_free as a matching deallocator Recognize __builtin_free as being equivalent to free when passed into __attribute__((malloc ())), similar to how it is treated when it is encountered as a call. This fixes spurious warnings in glibc where xmalloc family of allocators as well as reallocarray, memalign, etc. are declared to have __builtin_free as the free function. gcc/analyzer/ChangeLog: * sm-malloc.cc (malloc_state_machine::get_or_create_deallocator): Recognize __builtin_free. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/attr-malloc-1.c (compatible_alloc, compatible_alloc2): New extern allocator declarations. (test_9, test_10): New tests. --- diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index 9707a68..1d69d57 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -1511,7 +1511,8 @@ malloc_state_machine::get_or_create_deallocator (tree deallocator_fndecl) /* Reuse "free". */ deallocator *d; if (is_named_call_p (deallocator_fndecl, "free") - || is_std_named_call_p (deallocator_fndecl, "free")) + || is_std_named_call_p (deallocator_fndecl, "free") + || is_named_call_p (deallocator_fndecl, "__builtin_free")) d = &m_free.m_deallocator; else { diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c index 3de32b1..a9a2a3d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c @@ -11,6 +11,12 @@ extern struct foo *foo_acquire (void) extern void use_foo (const struct foo *) __attribute__((nonnull)); +extern struct foo *compatible_alloc (void) + __attribute__ ((malloc (__builtin_free))); + +extern struct foo *compatible_alloc2 (void) + __attribute__ ((malloc (free))); + void test_1 (void) { struct foo *p = foo_acquire (); @@ -73,3 +79,16 @@ int test_8 (struct foo *p) foo_release (p); return p->m_int; /* { dg-warning "use after 'foo_release' of 'p'" } */ } + +/* Recognize that __builtin_free and free are the same thing. */ +void test_9 (void) +{ + struct foo *p = compatible_alloc (); + free (p); +} + +void test_10 (void) +{ + struct foo *p = compatible_alloc2 (); + __builtin_free (p); +}