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 }