Description
The clang-analyzer incorrectly models the default ~
function for a union
object (it calls ~
on some of the options, in contradiction to the C++ standard and actual implementation which does not call ~
on any fields). This results in declaration of double-frees (or lost memory) which don't actually occur at runtime for sample code like this.
cat dtor-test.cpp
#include <iostream>
#include <optional>
class C {
int *once;
public:
C(int) {
std::cout << "C Ctor" << std::endl;
once = new int[3];
}
C(C&&) = delete;
~C() {
std::cout << "C Dtor" << std::endl;
delete[] once;
}
};
int main() {
std::optional<C> S{1};
return 0;
}
$ clang++ -fPIE -std=c++20 dtor-test.cpp && ./a.out # demo that clang++ runs correctly
C Ctor
C Dtor
$ g++ -fPIE -std=c++20 dtor-test.cpp && ./a.out # demo that g++ runs correctly
C Ctor
C Dtor
$ clang++ --analyze -analyzer-output=text -std=c++20 dtor-test.cpp # demo that clang-analyzer is wrong
dtor-test.cpp:14:5: warning: Attempt to free released memory [cplusplus.NewDelete]
14 | delete[] once;
| ^