This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/79254] [5/6/7 Regression] basic_string::operator= isn't exception safe


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

--- Comment #7 from Daryl Haresign <gcc-bugzilla at daryl dot haresign.com> ---
I would also be inclined to reverse your Guard: have it take 'this', have an
'activate' method which swaps in the new values, have a 'deactivate' method
which releases the memory, and have its destructor swap back the old values. 
Something like this (formatting and naming aside):

void
_M_copy_assign(const basic_string& __str, true_type)
{
  struct _Guard {
    _Guard(basic_string *__s)
    : _M_self(__s)
    , _M_alloc(_M_self->_M_get_allocator())
    {
    }

    ~_Guard() {
      if (_M_ptr)
        {
          _M_self->_M_data(_m_ptr);
          _M_self->_M_set_length(_M_size)
          _M_self->_M_get_allocator() = _M_alloc;
        }
    }

    void _M_activate() {
        _M_ptr = _M_self->_M_data();
        _M_size = _M_self->_M_allocated_capacity;
        _M_self->_M_data(_M_local_data());
        _M_self->_M_set_length(0);
    }

    void _M_deactivate() {
      if (_M_ptr)
        {
          _Alloc_traits::deallocate(_M_alloc, _M_ptr, _M_size + 1);
          _M_ptr = nullptr;
        }
    }

    basic_string *_M_self;
    allocator_type _M_alloc;
    pointer _M_ptr = nullptr;
    size_type _M_size = 0;
  };
  _Guard __guard(this);
  if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
      && _M_get_allocator() != __str._M_get_allocator())
    {
      // Replacement allocator cannot free existing storage.
      __guard._M_activate();
    }
  _M_get_allocator() = __str._M_get_allocator();
  this->_M_assign(__str);
  __guard._M_deactivate();
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]