| Issue |
164084
|
| Summary |
Clang analyzer false positive for unique_ptr inside std::pair
|
| Labels |
clang,
false-positive
|
| Assignees |
|
| Reporter |
bepaald
|
The following code causes `c++-analyzer` to emit a warning:
```c++
#include <memory>
#include <openssl/evp.h>
std::pair<std::unique_ptr<unsigned char[]>, int> decryptA(unsigned char *encdata, int enclength)
{
std::pair<std::unique_ptr<unsigned char[]>, int> decrypted{new unsigned char[enclength], enclength};
std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)> ctx(EVP_CIPHER_CTX_new(), &::EVP_CIPHER_CTX_free);
if (EVP_DecryptUpdate(ctx.get(), decrypted.first.get(), &decrypted.second, encdata, enclength) != 1)
return {nullptr, 0};
return decrypted;
}
```
```console
[~] $ /usr/lib/clang/c++-analyzer -c main93.cc
main93.cc:14:10: warning: Potential leak of memory pointed to by 'decrypted.first._M_t._M_t._M_head_impl' [cplusplus.NewDeleteLeaks]
14 | return decrypted;
| ^~~~~~~~~
1 warning generated.
```
I believe this is a false positive (but let me know if I'm mistaken). This is version 20.1.8, running on Arch Linux.
Apologies that the code depends on openssl, if I change the call to `EVP_DecryptUpdate()` to anything else the warning goes away:
```c++
/* !! NO MEMORY LEAK REPORTED FROM THIS CODE !! */
/* Only change: replace EVP_DecryptUpdate with a dummy function with the same signature */
#include <memory>
#include <openssl/evp.h>
int dummy(EVP_CIPHER_CTX *, unsigned char *, int *, unsigned char *, int);
std::pair<std::unique_ptr<unsigned char[]>, int> decryptC(unsigned char *encdata, int enclength)
{
std::pair<std::unique_ptr<unsigned char[]>, int> decrypted{new unsigned char[enclength], enclength};
std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)> ctx(EVP_CIPHER_CTX_new(), &::EVP_CIPHER_CTX_free);
if (dummy(ctx.get(), decrypted.first.get(), &decrypted.second, encdata, enclength) != 1)
return {nullptr, 0};
return decrypted;
}
```
Similarly, if I do not put the `std::unique_ptr` and `int` together in a `std::pair`, but keep them separate (until returning from the function), the problem also goes away.
```c++
/* !! NO MEMORY LEAK REPORTED FROM THIS CODE !! */
/* Only change: do not save the unique_ptr and int in a pair, but keep them separate until the return statement */
#include <memory>
#include <openssl/evp.h>
std::pair<std::unique_ptr<unsigned char[]>, int> decryptB(unsigned char *encdata, int enclength)
{
std::unique_ptr<unsigned char[]> decrypted_first(new unsigned char[enclength]);
int decrypted_second = enclength;
std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)> ctx(EVP_CIPHER_CTX_new(), &::EVP_CIPHER_CTX_free);
if (EVP_DecryptUpdate(ctx.get(), decrypted_first.get(), &decrypted_second, encdata, enclength) != 1)
return {nullptr, 0};
return std::make_pair(std::move(decrypted_first), decrypted_second);
}
```
Thanks!
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs