void alloc() { int *arr = new int [10]; delete arr; } GCC with -Wall -Wextra - No warnings. Clang with -Wall -Wextra: <source>:5:5: warning: 'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'? [-Wmismatched-new-delete] delete arr; ^ [] <source>:4:16: note: allocated with 'new[]' here int *arr = new int [10];
Confirmed. I'm working on general support for this sort of detection (see also pr94527).
Here is a little test case: // bad alloc & dealloc # include <stdlib.h> void f() { char * p = new char [ 10]; delete p; char * p2 = new char; delete [] p2; char * q = new char [ 10]; free( q); char * q2 = (char *) malloc( 10); delete [] q2; } Latest gcc finds no problems, latest clang finds two, for p and p2. q and q2 not found. Interestingly, I've just started compiling all of fedora distribution with clang. I've only compiled [a-d]*.spec files so far, but I have 34 cases found already. This implies about 220 cases in fedora. So only duplicating what does clang for new and delete would find hundreds of bugs in fedora. I'd be glad to help with testing any prototype implementation.
With the patch I'm testing GCC reports the following for the test case in comment #2: 90629-c2.C: In function ‘void f()’: 90629-c2.C:8:16: warning: ‘void operator delete(void*, long unsigned int)’ called on pointer returned from a mismatched allocation function [-Wmismatched-new-delete] 8 | delete p; | ^ 90629-c2.C:7:33: note: returned from a call to ‘void* operator new [](long unsigned int)’ 7 | char * p = new char [ 10]; | ^ 90629-c2.C:11:19: warning: ‘void operator delete [](void*)’ called on pointer returned from a mismatched allocation function [-Wmismatched-new-delete] 11 | delete [] p2; | ^~ 90629-c2.C:10:25: note: returned from a call to ‘void* operator new(long unsigned int)’ 10 | char * p2 = new char; | ^~~~ 90629-c2.C:17:19: warning: ‘void operator delete [](void*)’ called on pointer returned from a mismatched allocation function [-Wmismatched-new-delete] 17 | delete [] q2; | ^~ 90629-c2.C:16:36: note: returned from a call to ‘void* malloc(size_t)’ 16 | char * q2 = (char *) malloc( 10); | ~~~~~~^~~~~ The call to free(q) isn't diagnosed in the simple test case because it's eliminated by the cddce pass along with the new expression.
Patch: https://gcc.gnu.org/pipermail/gcc-patches/2020-November/557987.html
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>: https://gcc.gnu.org/g:dce6c58db87ebf7f4477bd3126228e73e4eeee97 commit r11-5732-gdce6c58db87ebf7f4477bd3126228e73e4eeee97 Author: Martin Sebor <msebor@redhat.com> Date: Thu Dec 3 15:41:25 2020 -0700 Add support for detecting mismatched allocation/deallocation calls. PR c++/90629 - Support for -Wmismatched-new-delete PR middle-end/94527 - Add an __attribute__ that marks a function as freeing an object gcc/ChangeLog: PR c++/90629 PR middle-end/94527 * builtins.c (access_ref::access_ref): Initialize new member. (compute_objsize): Use access_ref::deref. Handle simple pointer assignment. (expand_builtin): Remove handling of the free built-in. (call_dealloc_argno): Same. (find_assignment_location): New function. (fndecl_alloc_p): Same. (gimple_call_alloc_p): Same. (call_dealloc_p): Same. (matching_alloc_calls_p): Same. (warn_dealloc_offset): Same. (maybe_emit_free_warning): Same. * builtins.h (struct access_ref): Declare new member. (maybe_emit_free_warning): Make extern. Make use of access_ref. Handle -Wmismatched-new-delete. * calls.c (initialize_argument_information): Call maybe_emit_free_warning. * doc/extend.texi (attribute malloc): Update. * doc/invoke.texi (-Wfree-nonheap-object): Expand documentation. (-Wmismatched-new-delete): Document new option. (-Wmismatched-dealloc): Document new option. gcc/c-family/ChangeLog: PR c++/90629 PR middle-end/94527 * c-attribs.c (handle_dealloc_attribute): New function. (handle_malloc_attribute): Handle argument forms of attribute. * c.opt (-Wmismatched-dealloc): New option. (-Wmismatched-new-delete): New option. gcc/testsuite/ChangeLog: PR c++/90629 PR middle-end/94527 * g++.dg/asan/asan_test.cc: Fix a bug. * g++.dg/warn/delete-array-1.C: Add expected warning. * g++.old-deja/g++.other/delete2.C: Add expected warning. * g++.dg/warn/Wfree-nonheap-object-2.C: New test. * g++.dg/warn/Wfree-nonheap-object.C: New test. * g++.dg/warn/Wmismatched-new-delete.C: New test. * g++.dg/warn/Wmismatched-dealloc-2.C: New test. * g++.dg/warn/Wmismatched-dealloc.C: New test. * gcc.dg/Wmismatched-dealloc.c: New test. * gcc.dg/analyzer/malloc-1.c: Prune out expected warning. * gcc.dg/attr-malloc.c: New test. * gcc.dg/free-1.c: Adjust text of expected warning. * gcc.dg/free-2.c: Same. * gcc.dg/torture/pr71816.c: Prune out expected warning. * gcc.dg/tree-ssa/pr19831-2.c: Add an expected warning. * gcc.dg/Wfree-nonheap-object-2.c: New test. * gcc.dg/Wfree-nonheap-object-3.c: New test. * gcc.dg/Wfree-nonheap-object.c: New test. libstdc++-v3/ChangeLog: * testsuite/ext/vstring/modifiers/clear/56166.cc: Suppress a false positive warning.
Done for GCC 11.