https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109568
Bug ID: 109568
Summary: [12/13 Regression] Spurious "potential null pointer
dereference" in shared_ptr_base.h with "-O1"
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: zed.three at gmail dot com
Target Milestone: ---
The following MVCE gives a warning about a potential null dereference in
operator== in shared_ptr_base.h:
#include <memory>
struct Base {
virtual ~Base() = default;
bool empty() { return ptr == nullptr; }
std::shared_ptr<int> ptr{nullptr};
};
struct Derived : public Base {};
bool empty(Base* var) {
auto* var_ref = dynamic_cast<Derived*>(var);
if (var_ref->empty()) return false;
return true;
}
Compiler Explorer link: https://godbolt.org/z/Tqrdo61Ks
Warning:
In file included from
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/shared_ptr.h:53,
from
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/memory:77,
from <source>:1:
In member function 'std::__shared_ptr<_Tp, _Lp>::operator bool() const [with
_Tp = int; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]',
inlined from 'bool std::operator==(const shared_ptr<_Tp>&, nullptr_t)
[with _Tp = int]' at
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/shared_ptr.h:562:14,
inlined from 'bool Base::empty() const' at <source>:5:46,
inlined from 'bool empty(Base*)' at <source>:12:23:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/shared_ptr_base.h:1670:16:
error: potential null pointer dereference [-Werror=null-dereference]
1670 | { return _M_ptr != nullptr; }
|
This requires at least -O1 and appears in GCC 12.1 onwards. The `dynamic_cast`
also appears to be necessary, as `std::shared_ptr<int>{nullptr} == nullptr`
doesn't trigger the warning.