Index: llvm/lib/MC/MCStreamer.cpp =================================================================== --- llvm/lib/MC/MCStreamer.cpp +++ llvm/lib/MC/MCStreamer.cpp @@ -692,6 +692,8 @@ MCSymbol *Label = emitCFILabel(); CurFrame->End = Label; + if (!CurFrame->FuncletOrFuncEnd) + CurFrame->FuncletOrFuncEnd = CurFrame->End; } void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) { Index: llvm/lib/MC/MCWin64EH.cpp =================================================================== --- llvm/lib/MC/MCWin64EH.cpp +++ llvm/lib/MC/MCWin64EH.cpp @@ -504,8 +504,11 @@ int64_t RawFuncLength; if (!info->FuncletOrFuncEnd) { - // FIXME: This is very wrong; we emit SEH data which covers zero bytes - // of code. But otherwise test/MC/AArch64/seh.s crashes. + // This can happen if unwind info is forced to be generated at a point + // where the end of the function hasn't been determined yet, and where + // the current section at the time of generating the unwind info wasn't + // the text section, so we weren't able to automatically add a + // FuncletOrFuncEnd label. RawFuncLength = 0; } else { // FIXME: GetAbsDifference tries to compute the length of the function @@ -663,6 +666,9 @@ void llvm::Win64EH::ARM64UnwindEmitter::Emit(MCStreamer &Streamer) const { // Emit the unwind info structs first. for (const auto &CFI : Streamer.getWinFrameInfos()) { + if (!CFI->FuncletOrFuncEnd && + Streamer.getCurrentSectionOnly() == CFI->TextSection) + CFI->FuncletOrFuncEnd = Streamer.emitCFILabel(); MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection); Streamer.SwitchSection(XData); ARM64EmitUnwindInfo(Streamer, CFI.get()); @@ -680,6 +686,9 @@ MCStreamer &Streamer, WinEH::FrameInfo *info) const { // Switch sections (the static function above is meant to be called from // here and from Emit(). + if (!info->FuncletOrFuncEnd && + Streamer.getCurrentSectionOnly() == info->TextSection) + info->FuncletOrFuncEnd = Streamer.emitCFILabel(); MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection); Streamer.SwitchSection(XData); ARM64EmitUnwindInfo(Streamer, info); Index: llvm/test/MC/AArch64/seh.s =================================================================== --- llvm/test/MC/AArch64/seh.s +++ llvm/test/MC/AArch64/seh.s @@ -48,6 +48,17 @@ // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: UnwindInformation [ +// CHECK-NEXT: RuntimeFunction { +// CHECK-NEXT: Function: func +// CHECK-NEXT: ExceptionRecord: .xdata +// CHECK-NEXT: ExceptionData { +// CHECK-NEXT: FunctionLength: 8 +// CHECK: RuntimeFunction { +// CHECK-NEXT: Function: smallFunc +// CHECK-NEXT: ExceptionRecord: .xdata +// CHECK-NEXT: ExceptionData { +// CHECK-NEXT: FunctionLength: 4 .text .globl func