Bug 90629 - Support for -Wmismatched-new-delete
Summary: Support for -Wmismatched-new-delete
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 11.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic, patch
Depends on:
Blocks: new-warning, new_warning
  Show dependency treegraph
 
Reported: 2019-05-25 12:28 UTC by Dávid Bolvanský
Modified: 2023-12-30 02:28 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-04-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dávid Bolvanský 2019-05-25 12:28:33 UTC
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];
Comment 1 Martin Sebor 2020-04-13 20:15:14 UTC
Confirmed.  I'm working on general support for this sort of detection (see also pr94527).
Comment 2 David Binderman 2020-08-27 07:51:18 UTC
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.
Comment 3 Martin Sebor 2020-10-20 15:30:01 UTC
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.
Comment 5 GCC Commits 2020-12-03 22:43:50 UTC
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.
Comment 6 Martin Sebor 2020-12-03 22:44:49 UTC
Done for GCC 11.