This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/77896] Object vtable lookups are not hoisted out of loops
- From: "scovich at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sat, 08 Oct 2016 13:30:51 +0000
- Subject: [Bug c++/77896] Object vtable lookups are not hoisted out of loops
- Auto-submitted: auto-generated
- References: <bug-77896-4@http.gcc.gnu.org/bugzilla/>
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