msgpack / msgpack-c

MessagePack implementation for C and C++ / msgpack.org[C/C++]
Other
3.01k stars 875 forks source link

Memory cleaned up multiple times #1098

Open mgovers opened 11 months ago

mgovers commented 11 months ago

Describe the bug according to the Clang static analyzer, msgpack::zone calls ::free on memory that has been cleaned up before: https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-newdelete

Verified to be in msgpack-cxx version 6.1.0, but likely also present in all older versions starting with v1.

To Reproduce Compile the following code using the Clang Analyzer:

#include <msgpack.hpp>

#include <memory>

namespace {
struct Foo {
    std::unique_ptr<msgpack::zone> zone;
};
} // namespace

int main() {
    Foo const foo{};
    return 0;
}

This results in the following output:

[build] "<...>/cmake.exe" -E __run_co_compile --tidy=clang-tidy.exe;--extra-arg=/EHsc;--extra-arg-before=--driver-mode=cl --source=<source_dir>/source.cpp -- <...>/clang-cl.exe  /nologo -TP  -imsvc<std_lib> /DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -std:c++20 -MDd /showIncludes /Fo<build_dir>/test_tmp.cpp.obj /Fd<build_dir>\ -c -- <source_dir>/source.cpp
[build] <msgpack_dir>/include/msgpack/v1/detail/cpp11_zone.hpp:197:9: error: Attempt to free released memory [clang-analyzer-cplusplus.NewDelete,-warnings-as-errors]
[build]         ::free(p);
[build]         ^
[build] <source_dir>/source.cpp:15:12: note: Calling implicit destructor for 'Foo'
[build]     return 0;
[build]            ^
[build] <source_dir>/source.cpp:15:12: note: Calling '~unique_ptr'
[build] <std_lib>/memory:3289:13: note: Assuming field '_Myval2' is non-null
[build]         if (_Mypair._Myval2) {
[build]             ^~~~~~~~~~~~~~~
[build] <std_lib>/memory:3289:9: note: Taking true branch
[build]         if (_Mypair._Myval2) {
[build]         ^
[build] <std_lib>/memory:3290:13: note: Calling 'default_delete::operator()'
[build]             _Mypair._Get_first()(_Mypair._Myval2);
[build]             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[build] <std_lib>/memory:3180:9: note: Memory is released
[build]         delete _Ptr;
[build]         ^~~~~~~~~~~
[build] <std_lib>/memory:3180:9: note: Calling 'zone::operator delete'
[build]         delete _Ptr;
[build]         ^~~~~~~~~~~
[build] <msgpack_dir>/include/msgpack/v1/detail/cpp11_zone.hpp:197:9: note: Attempt to free released memory
[build]         ::free(p);
[build]         ^~~~~~~~~

Expected behavior The above example compiles correctly.