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 c++/77896] Object vtable lookups are not hoisted out of loops


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

--- Comment #4 from Ryan Johnson <scovich at gmail dot com> ---
Yikes. That explains it, all right. 

I never would have thought of an object destroying itself and changing its type
with placement new... I guess it must be subject to the same restrictions as
`delete this` [1], because things don't turn out well if the compiler thinks it
knows the type of the object:

==== alter.cpp =======
#include <cstdio>
#include <new>

struct AlterEgo {
   virtual ~AlterEgo() { }
   virtual void toggle()=0;
};

struct Jekyl : AlterEgo {
   ~Jekyl() { puts("~Jekyl"); }
   void toggle();
};

struct Hyde : AlterEgo {
   ~Hyde() { puts("~Hyde"); }
   void toggle();
};

void Jekyl::toggle()
{ this->~AlterEgo(); new (this) Hyde; }
void Hyde::toggle()
{ this->~AlterEgo(); new (this) Jekyl; }

void whatami(AlterEgo* x)
{
   printf("Jekyl? %p\n", dynamic_cast<Jekyl*>(x));
   x->toggle();
   printf("Jekyl? %p\n", dynamic_cast<Jekyl*>(x));
}

int main()
{
   puts("\nWorks ok-ish:");
   Jekyl* x = new Jekyl;
   whatami(x);
   puts("\nJekyl?");
   delete x;

   puts("\nBad idea:");
   Jekyl j;
   j.toggle();
   j.toggle();
   whatami(&j);

   puts("\nJekyl?");
}
====================

$ g++ -Wall alter.cpp && ./a.out

Works ok-ish:
Jekyl? 0x6000104c0
~Jekyl
Jekyl? 0x0

Jekyl?
~Hyde

Bad idea:
~Jekyl
~Hyde
Jekyl? 0x0
~Hyde
Jekyl? 0xffffcbf0

Jekyl?
~Jekyl

[1] https://isocpp.org/wiki/faq/freestore-mgmt#delete-this

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