https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78444
Bug ID: 78444 Summary: Wrong prologue stack alignment for implicit dtor on x86_64-darwin* Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: iains at gcc dot gnu.org Target Milestone: --- Created attachment 40095 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40095&action=edit stand-alone reproducer (c++11) -std=c++11 -fno-exceptions -fno-rtti In this code, there's an implict dtor which calls a base class dtor. The stack is incorrectly aligned at the call to the second dtor (leading to dyld complaining and aborting the code). .globl __ZN4llvm2cl6parserIjED1Ev .weak_definition __ZN4llvm2cl6parserIjED1Ev __ZN4llvm2cl6parserIjED1Ev: LFB15: pushq %rbp LCFI21: movq %rsp, %rbp LCFI22: subq $8, %rsp movq %rdi, -8(%rbp) movq -8(%rbp), %rax movq %rax, %rdi call __ZN4llvm2cl12basic_parserIjED2Ev leave LCFI23: ret LFE15: ===== AFAICT has been present since c++11 introduction in 4.7 (so seems to be an infrequently triggered issue). I can't see any particular reason why this is Darwin-specific (the x86_64 code in the back end has very little Darwin conditional code). However, it looks like Linux clones the dtor (_ZN4llvm2cl6parserIjED2Ev) and generates correct prologue code for that. So it's not clear if this is Darwin-specific, or just that the fail conditions are only triggered for Darwin. Looking at the tree dumps, the dtors look like regular weak hidden functions. ==== Looking at the incoming state to ix86_expand_prologue, it seems that the function is expecting the stack_alignment_needed to be already set to a valid amount. with some debug code at the entry of ix86_expand_prologue(): $ ./prev-gcc/xg++ -Bprev-gcc -fno-exceptions -fno-rtti /Volumes/sc3_src/test-cxx/prologue-x86-64-bug.C -S _ZN4llvm2cl6OptionD2Ev : is leaf Y incoming 128 set align_needed 64 realign N _ZN4llvm2cl12basic_parserIjED2Ev : is leaf Y incoming 128 set align_needed 64 realign N _ZN4llvm2cl12basic_parserIjED1Ev : is leaf Y incoming 128 set align_needed 64 realign N _ZN4llvm2cl3optIjLb0ENS0_6parserIjEEE16handleOccurrenceEjNS_9StringRefES5_ : is leaf Y incoming 128 set align_needed 64 realign N _ZNK4llvm2cl3optIjLb0ENS0_6parserIjEEE16printOptionValueEjb : is leaf Y incoming 128 set align_needed 64 realign N _ZN4llvm2cl6parserIjED1Ev : is leaf N incoming 128 set align_needed 64 realign N _ZN4llvm2cl3optIjLb0ENS0_6parserIjEEED1Ev : is leaf N incoming 128 set align_needed 128 realign N _ZN4llvm2cl3optIjLb0ENS0_6parserIjEEED0Ev : is leaf N incoming 128 set align_needed 128 realign N Notice that _ZN4llvm2cl6parserIjED1Ev is not a leaf function, but only claims to need 64b alignment. If I hack the following into ix86_finalize_stack_realign_flags() if (TARGET_MACHO && TARGET_64BIT && !crtl->is_leaf) { /* Darwin needs at least 128b alignment at function calls. */ crtl->stack_alignment_needed = crtl->stack_alignment_needed < 128 ? 128 : crtl->stack_alignment_needed; crtl->preferred_stack_boundary = crtl->preferred_stack_boundary < 128 ? 128 : crtl->preferred_stack_boundary; } it works around the issue. So the questions are; 1. are preceding phases (e.g. cfgexpand) supposed to make target callbacks that get this right? 2. is something missing in the pro/epilogue that's supposed to detect this case and fix it up?