$ cat fake_bomber.cpp struct bomber { bomber() : bum( false ) { } ~bomber() { if ( bum ) throw 0; } // this will never throw private: bool bum; };
void zoo() { } void bar( void ( *f )() ) { #ifndef CALL2JMP bomber b; // fake bomber #endif f(); } void foo() { #ifndef CALL2JMP bomber b; // fake bomber #endif bar( &zoo ); } int main() { foo(); return 0; } $ g++ fake_bomber.cpp -o fake_bomber -O3 -fno-rtti --save-temps zoo(): rep ; ret bar(void (*)()): subq $8, %rsp call *%rdi addq $8, %rsp ret movq %rax, %rdi call _Unwind_Resume foo(): subq $8, %rsp movl zoo(), %edi call bar(void (*)()) addq $8, %rsp ret movq %rax, %rdi call _Unwind_Resume main: subq $8, %rsp call foo() xorl %eax, %eax addq $8, %rsp ret $ g++ fake_bomber.cpp -o fake_bomber -O3 -fno-rtti --save-temps -DCALL2JMP zoo(): rep ; ret bar(void (*)()): movq %rdi, %r11 jmp *%r11 foo(): rep ; ret main: xorl %eax, %eax ret -- Summary: missed call -> jmp transformation; redundant unwind stuff. Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: pluto at agmk dot net GCC target triplet: x86-64-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28850