Bug 87731 - Detection of mismatched alloc/free pairs
Summary: Detection of mismatched alloc/free pairs
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 8.2.0
: P3 enhancement
Target Milestone: 11.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic
Depends on:
Blocks: new-warning, new_warning 87736
  Show dependency treegraph
 
Reported: 2018-10-24 13:13 UTC by Daniel Fruzynski
Modified: 2023-12-30 02:18 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-10-24 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Fruzynski 2018-10-24 13:13:59 UTC
Following code compiles cleanly on gcc:

void foo()
{
    char* c = new char[4];
    delete c;
}

When it is compiles using clang 7.0.0, it generates following warning. Please do the same in gcc.

<source>:4:5: warning: 'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'? [-Wmismatched-new-delete]
    delete c;
    ^
          []
<source>:3:15: note: allocated with 'new[]' here
    char* c = new char[4];
              ^
1 warning generated.
Compiler returned: 0

Valgrind also has similar diagnostics, it checks checks following pairs by default: malloc/free, new/delete, new[]/delete[]. Please implement something similar in gcc.

Valgrind also provides set of macros which allows it to track custom alloc/free functions. It would be nice if you add new attributes which could be attached to custom alloc and free functions, so gcc could check pairing for them too. I think of something like this:

__attribute__((malloc("MyAllocType")))
void* MyAlloc(size_t);

__attribute__((free("MyAllocType")))
void MyFree(void*);
Comment 1 Jonathan Wakely 2018-10-24 15:27:09 UTC
With -fsanitize=address GCC diagnoses it.
Comment 2 Jonathan Wakely 2018-10-24 15:33:00 UTC
(In reply to Daniel Fruzynski from comment #0)
> Valgrind also provides set of macros which allows it to track custom
> alloc/free functions. It would be nice if you add new attributes which could
> be attached to custom alloc and free functions, so gcc could check pairing
> for them too. I think of something like this:
> 
> __attribute__((malloc("MyAllocType")))
> void* MyAlloc(size_t);
> 
> __attribute__((free("MyAllocType")))
> void MyFree(void*);

That should be a separate enhancement request.
Comment 3 Daniel Fruzynski 2018-10-24 16:39:02 UTC
Logged Bug 87736 for new proposed attributes.
Comment 4 Martin Sebor 2018-10-24 16:44:41 UTC
We have been discussing this feature for some time now.  Not just the diagnostics but also the significant optimization opportunities here.

Detecting the simple cases is fairly easy but of only limited value.  The more interesting cases are harder to handle (and Clang doesn't).  For example, the bug in the common idiom below isn't diagnosed:

  void f (void*);

  void g (int n)
  {
    char a[8];
    char *p;
    if (n <= 8)
      p = a;
    else
      p = new char[n];

    f (p);

    if (p != a)    
      delete p;
  }

I think marking up related sets of functions (like calloc/malloc/realloc + free) is necessary for a general solution.  Otherwise it will be limited only to the subset known/visible to the compiler: i.e., built-ins and inlined functions.  Beyond function attributes like those suggested in comment #0, it might be helpful to also provide a similar annotation for pointer variables (especially members) so that the compiler can make assumptions about the allocation/deallocation functions expected to be used with them even across calls to functions without any annotation.
Comment 5 Martin Sebor 2018-10-24 17:07:56 UTC
Like pr87736, this is also a general mechanism, not one specific to C++, so changing Component to middle-end.
Comment 6 Martin Sebor 2019-11-08 02:31:33 UTC
See also pr91582 for a related project (the detection could be done in the strlen pass that's being enhanced to track dynamic memory allocation, or it could be done in a separate pass of its own, at the cost of duplicating some functionality).
Comment 7 Martin Sebor 2020-10-27 01:50:32 UTC
Testing a prototype patch (see also pr80532).
Comment 8 Martin Sebor 2020-12-03 22:48:02 UTC
Implemented for GCC 11 in r11-5732.