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.