[Bug c++/67557] Calling copy constructor of base class in constructor of derived class produces crashing code

redi at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Sep 14 00:36:00 GMT 2015


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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
namespace std
{
struct string
{
  typedef unsigned long size_type;
  const char* _M_p;
  char        _M_local_buf[1];

  string(const char* s) : _M_p(_M_local_buf)
  {
    __builtin_printf("%p constructed\n", this);
  }

  string(const string& s) : _M_p(_M_local_buf)
  {
    __builtin_printf("%p copied from %p\n", this, &s);
  }

  ~string()
  {
    __builtin_printf("%p destroyed\n", this);
    if (_M_p != _M_local_buf)
      __builtin_abort();
  }
};
}

struct StartTag
{
        explicit StartTag(std::string const & tag) : tag_(tag),
keepempty_(false) {}
        std::string tag_;
        bool keepempty_;
};

StartTag fontToStartTag() { return StartTag(""); }

struct FontTag : public StartTag
{
        FontTag() : StartTag(fontToStartTag()) {}
};

int main()
{
        FontTag x;
        __builtin_printf("%p x.tag_ in main()\n", &x.tag_);
        return 0;
}


This prints:

0x7ffdd31bbb60 constructed
0x7ffdd31bbb90 copied from 0x7ffdd31bbb60
0x7ffdd31bbb60 destroyed
0x7ffdd31bbbe0 x.tag_ in main()
0x7ffdd31bbbe0 destroyed
Aborted (core dumped)

Note that the 'this' pointer in the copy constructor is 0x7fffde6c4d20, which
is not the address of x.tag_ and not the address in the destructor.

The string copy constructor sets its _M_p member to point to this->_M_local_buf
using the incorrect value of 'this' and then in the destructor sees _M_p !=
_M_local_buf (which in the real std::string tries to delete[] _M_p which
crashes).



More information about the Gcc-bugs mailing list