Open
Description
#include <memory>
#include <cstring>
#include <string>
struct Repro {
std::unique_ptr<int> m_ptr;
struct Other {
char url[256];
};
char m_buff[1000];
void CopyIn()
{
auto other = (Other *)m_buff;
std::string local_url = "foo bar";
strncpy(other->url, local_url.c_str(), sizeof(other->url) - 1);
}
};
void
bug()
{
Repro rep;
rep.m_ptr = std::make_unique<int>();
rep.CopyIn();
}
clang-tidy
reports the following when building against the GCC-15's libstdc++:
repro.cpp:19:5: error: Potential leak of memory pointed to by field '_M_head_impl' [clang-analyzer-cplusplus.NewDeleteLeaks,-warnings-as-errors]
19 | }
| ^
repro.cpp:26:17: note: Calling 'make_unique<int, >'
26 | rep.m_ptr = std::make_unique<int>();
| ^~~~~~~~~~~~~~~~~~~~~~~
/opt/gcc-15/lib/gcc/x86_64-pc-linux-gnu/15.1.1/../../../../include/c++/15.1.1/bits/unique_ptr.h:1085:30: note: Memory is allocated
1085 | { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
repro.cpp:26:17: note: Returned allocated memory
26 | rep.m_ptr = std::make_unique<int>();
| ^~~~~~~~~~~~~~~~~~~~~~~
repro.cpp:27:5: note: Calling 'Repro::CopyIn'
27 | rep.CopyIn();
| ^~~~~~~~~~~~
repro.cpp:19:5: note: Potential leak of memory pointed to by field '_M_head_impl'
19 | }
| ^
There is clearly no leak here and the warning goes away if the code is tweaked just a little bit... I cannot understand
Activity
ns-osmolsky commentedon Jun 11, 2025
I cannot understand why/how this code gets flagged by the analyzer... especially given that tiny changes such as this eliminate the warning:
llvmbot commentedon Jun 11, 2025
@llvm/issue-subscribers-clang-static-analyzer
Author: Oleg Smolsky (ns-osmolsky)
struct Repro {
std::unique_ptr<int> m_ptr;
};
void
bug()
{
Repro rep;
rep.m_ptr = std::make_unique<int>();
rep.CopyIn();
}
repro.cpp:19:5: error: Potential leak of memory pointed to by field '_M_head_impl' [clang-analyzer-cplusplus.NewDeleteLeaks,-warnings-as-errors]
19 | }
| ^
repro.cpp:26:17: note: Calling 'make_unique<int, >'
26 | rep.m_ptr = std::make_unique<int>();
| ^~~~~~~~~~~~~~~~~~~~~~~
/opt/gcc-15/lib/gcc/x86_64-pc-linux-gnu/15.1.1/../../../../include/c++/15.1.1/bits/unique_ptr.h:1085:30: note: Memory is allocated
1085 | { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
repro.cpp:26:17: note: Returned allocated memory
26 | rep.m_ptr = std::make_unique<int>();
| ^~~~~~~~~~~~~~~~~~~~~~~
repro.cpp:27:5: note: Calling 'Repro::CopyIn'
27 | rep.CopyIn();
| ^~~~~~~~~~~~
repro.cpp:19:5: note: Potential leak of memory pointed to by field '_M_head_impl'
19 | }
| ^
steakhal commentedon Jun 12, 2025
Did you use clang tidy trunk?
ns-osmolsky commentedon Jun 12, 2025
This issue is present in 20.1.3 and 20.1.6. I have not tried Trunk.
ns-lwu commentedon Jun 13, 2025
Hope I get CE right.
Tried clang trunk and 20.1 both report the same issue
https://godbolt.org/z/MzWMxG6dr
ns-osmolsky commentedon Jun 13, 2025
The issue is still present in Trunk. Here is a direct repro with the
clang-tidy
selected as the tool: https://godbolt.org/z/MbM4c1Pdrns-osmolsky commentedon Jun 13, 2025
Here is a slightly reduced repro: eliminated casts and extra types.
steakhal commentedon Jun 13, 2025
Thabk you.
/CC @necto
necto commentedon Jun 13, 2025
I have stumbled upon a similar false positive raising when I use a custom deleter with
std::unique_ptr
. It seems to be caused by 9b2ec87A partial fix b756c82 did not cover the case of a copy-initialized deleter, so the false-positive with a custom deleter remains in Clang-20.
In your case, seems to be somewhat different, though, so I encourage you to try if FP appears before or after 9b2ec87
CStringChecker
#146212