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).