https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90221

            Bug ID: 90221
           Summary: Resource leak in object
           Product: gcc
           Version: 6.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: venkateshprabu at gmail dot com
  Target Milestone: ---

https://github.com/gcc-mirror/gcc/blob/gcc-6_4_0-release/libstdc++-v3/include/bits/shared_ptr_base.h#L646

Is this false positive by coverity ?

Coverity report:

  {
633          // _GLIBCXX_RESOLVE_LIB_DEFECTS
634          // 2415. Inconsistency between unique_ptr and shared_ptr
        1. Condition __r->get() == NULL, taking false branch.
635          if (__r.get() == nullptr)
636            return;
637
638          using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
639          using _Del2 = typename conditional<is_reference<_Del>::value,
640              reference_wrapper<typename remove_reference<_Del>::type>,
641              _Del>::type;
642          using _Sp_cd_type
643            = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
644          using _Alloc = allocator<_Sp_cd_type>;
645          using _Alloc_traits = allocator_traits<_Alloc>;
646          _Alloc __a;

CID 8655046 (#1 of 1): Resource leak in object (CTOR_DTOR_LEAK)
2. alloc_fn: Calling allocation function allocate. [show details]
        3. assign: Assigning: __mem =
std::allocator_traits<std::allocator<std::_Sp_counted_deleter<JCI::MediaBase::IAPVolumeManager
*, std::default_delete<JCI::MediaBase::IAPVolumeManager>, std::allocator<void>,
(__gnu_cxx::_Lock_policy)2> > >::allocate(__a, 1UL).
647          _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
648          _Alloc_traits::construct(__a, __mem, __r.release(),
649                                   __r.get_deleter());  // non-throwing
        4. assign: Assigning: this->_M_pi = __mem.
        5. ctor_dtor_leak: The constructor allocates field _M_pi of
std::__shared_count<(__gnu_cxx::_Lock_policy)2> but the destructor and whatever
functions it calls do not free it.
650          _M_pi = __mem;
651        }
652
653      // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
654      explicit __shared_count(const __weak_count<_Lp>& __r);
655
656      // Does not throw if __r._M_get_use_count() == 0, caller must check.
657      explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t);
658
        A1. destructor: This is the destructor implementation.
659      ~__shared_count() noexcept
660      {
661        if (_M_pi != nullptr)
662          _M_pi->_M_release();
663      }
664
665      __shared_count(const __shared_count& __r) noexcept
666      : _M_pi(__r._M_pi)
667      {
668        if (_M_pi != 0)
669          _M_pi->_M_add_ref_copy();
670      }
671
672      __shared_count&
673      operator=(const __shared_count& __r) noexcept
674      {
675        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
676        if (__tmp != _M_pi)
677          {
678            if (__tmp != 0)
679              __tmp->_M_add_ref_copy();
680            if (_M_pi != 0)
681              _M_pi->_M_release();
        CID 285739: Unsafe assignment operator (SELF_ASSIGN) [select issue]
682            _M_pi = __tmp;
683          }
684        return *this;
685      }
686
687      void
688      _M_swap(__shared_count& __r) noexcept
689      {
690        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
691        __r._M_pi = _M_pi;
692        _M_pi = __tmp;
693      }
694
695      long
696      _M_get_use_count() const noexcept
697      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
698
699      bool
700      _M_unique() const noexcept
701      { return this->_M_get_use_count() == 1; }
702
703      void*
704      _M_get_deleter(const std::type_info& __ti) const noexcept
705      { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
706
707      bool
708      _M_less(const __shared_count& __rhs) const noexcept
709      { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi,
__rhs._M_pi); }
710
711      bool
712      _M_less(const __weak_count<_Lp>& __rhs) const noexcept
713      { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi,
__rhs._M_pi); }
714
715      // Friend function injected into enclosing namespace and found by ADL
716      friend inline bool
717      operator==(const __shared_count& __a, const __shared_count& __b)
noexcept
718      { return __a._M_pi == __b._M_pi; }
719
720    private:
721      friend class __weak_count<_Lp>;
722
723      _Sp_counted_base<_Lp>*  _M_pi;
724    };
725
726
727  template<_Lock_policy _Lp>
728    class __weak_count
729    {
730    public:
731      constexpr __weak_count() noexcept : _M_pi(nullptr)
732      { }
733
734      __weak_count(const __shared_count<_Lp>& __r) noexcept
735      : _M_pi(__r._M_pi)
736      {
737        if (_M_pi != nullptr)
738          _M_pi->_M_weak_add_ref();
739      }
740
741      __weak_count(const __weak_count& __r) noexcept
742      : _M_pi(__r._M_pi)
743      {
744        if (_M_pi != nullptr)
745          _M_pi->_M_weak_add_ref();
746      }
747
748      __weak_count(__weak_count&& __r) noexcept
749      : _M_pi(__r._M_pi)
750      { __r._M_pi = nullptr; }
751
752      ~__weak_count() noexcept
753      {
754        if (_M_pi != nullptr)
755          _M_pi->_M_weak_release();
756      }
757
758      __weak_count&
759      operator=(const __shared_count<_Lp>& __r) noexcept
760      {
761        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
762        if (__tmp != nullptr)
763          __tmp->_M_weak_add_ref();
764        if (_M_pi != nullptr)
765          _M_pi->_M_weak_release();
766        _M_pi = __tmp;
767        return *this;
768      }
769
770      __weak_count&
771      operator=(const __weak_count& __r) noexcept
772      {
773        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
774        if (__tmp != nullptr)
775          __tmp->_M_weak_add_ref();
776        if (_M_pi != nullptr)
777          _M_pi->_M_weak_release();
        CID 285738: Unsafe assignment operator (SELF_ASSIGN) [select issue]
778        _M_pi = __tmp;
779        return *this;
780      }
781
782      __weak_count&
783      operator=(__weak_count&& __r) noexcept
784      {
785        if (_M_pi != nullptr)
786          _M_pi->_M_weak_release();
        CID 5529785: Unsafe assignment operator (SELF_ASSIGN) [select issue]
787        _M_pi = __r._M_pi;
788        __r._M_pi = nullptr;
789        return *this;
790      }
791
792      void
793      _M_swap(__weak_count& __r) noexcept
794      {
795        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
796        __r._M_pi = _M_pi;
797        _M_pi = __tmp;
798      }
799
800      long
801      _M_get_use_count() const noexcept
802      { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
803
804      bool
805      _M_less(const __weak_count& __rhs) const noexcept
806      { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi,
__rhs._M_pi); }
807
808      bool
809      _M_less(const __shared_count<_Lp>& __rhs) const noexcept
810      { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi,
__rhs._M_pi); }
811
812      // Friend function injected into enclosing namespace and found by ADL
813      friend inline bool
814      operator==(const __weak_count& __a, const __weak_count& __b) noexcept
815      { return __a._M_pi == __b._M_pi; }
816
817    private:
818      friend class __shared_count<_Lp>;
819
820      _Sp_counted_base<_Lp>*  _M_pi;
821    };
822
823  // Now that __weak_count is defined we can define this constructor:
824  template<_Lock_policy _Lp>
825    inline
826    __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
827    : _M_pi(__r._M_pi)
828    {
829      if (_M_pi != nullptr)
830        _M_pi->_M_add_ref_lock();
831      else
832        __throw_bad_weak_ptr();
833    }
834
835  // Now that __weak_count is defined we can define this constructor:
836  template<_Lock_policy _Lp>
837    inline
838    __shared_count<_Lp>::
839    __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t)
840    : _M_pi(__r._M_pi)
841    {
842      if (_M_pi != nullptr)
843        if (!_M_pi->_M_add_ref_lock_nothrow())
844          _M_pi = nullptr;
845    }
846
847  // Support for enable_shared_from_this.
848
849  // Friend of __enable_shared_from_this.
850  template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
851    void
852    __enable_shared_from_this_helper(const __shared_count<_Lp>&,
853                                     const __enable_shared_from_this<_Tp1,
854                                     _Lp>*, const _Tp2*) noexcept;
855
856  // Friend of enable_shared_from_this.
857  template<typename _Tp1, typename _Tp2>
858    void
859    __enable_shared_from_this_helper(const __shared_count<>&,
860                                     const enable_shared_from_this<_Tp1>*,
861                                     const _Tp2*) noexcept;
862
863  template<_Lock_policy _Lp>
864    inline void
865    __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
noexcept
866    { }
867
868
869  template<typename _Tp, _Lock_policy _Lp>
870    class __shared_ptr
871    {
872      template<typename _Ptr>
873        using _Convertible
874          = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
875
 876    public:
 877      typedef _Tp   element_type;
 878
 879      constexpr __shared_ptr() noexcept
 880      : _M_ptr(0), _M_refcount()
 881      { }
 882
 883      template<typename _Tp1>
 884        explicit __shared_ptr(_Tp1* __p)
 885        : _M_ptr(__p), _M_refcount(__p)
 886        {
 887          __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
 888          static_assert( !is_void<_Tp1>::value, "incomplete type" );
 889          static_assert( sizeof(_Tp1) > 0, "incomplete type" );
 890          __enable_shared_from_this_helper(_M_refcount, __p, __p);
 891        }

Reply via email to