compiler: ensure all defers have been seen before creating rundefers
Fixes #3643
Этот коммит содержится в:
родитель
1672610749
коммит
4326c8f10e
1 изменённых файлов: 19 добавлений и 1 удалений
|
@ -167,6 +167,8 @@ type builder struct {
|
||||||
deferExprFuncs map[ssa.Value]int
|
deferExprFuncs map[ssa.Value]int
|
||||||
selectRecvBuf map[*ssa.Select]llvm.Value
|
selectRecvBuf map[*ssa.Select]llvm.Value
|
||||||
deferBuiltinFuncs map[ssa.Value]deferBuiltin
|
deferBuiltinFuncs map[ssa.Value]deferBuiltin
|
||||||
|
runDefersBlock []llvm.BasicBlock
|
||||||
|
afterDefersBlock []llvm.BasicBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBuilder(c *compilerContext, irbuilder llvm.Builder, f *ssa.Function) *builder {
|
func newBuilder(c *compilerContext, irbuilder llvm.Builder, f *ssa.Function) *builder {
|
||||||
|
@ -1349,6 +1351,15 @@ func (b *builder) createFunction() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The rundefers instruction needs to be created after all defer
|
||||||
|
// instructions have been created. Otherwise it won't handle all defer
|
||||||
|
// cases.
|
||||||
|
for i, bb := range b.runDefersBlock {
|
||||||
|
b.SetInsertPointAtEnd(bb)
|
||||||
|
b.createRunDefers()
|
||||||
|
b.CreateBr(b.afterDefersBlock[i])
|
||||||
|
}
|
||||||
|
|
||||||
if b.hasDeferFrame() {
|
if b.hasDeferFrame() {
|
||||||
// Create the landing pad block, where execution continues after a
|
// Create the landing pad block, where execution continues after a
|
||||||
// panic.
|
// panic.
|
||||||
|
@ -1503,7 +1514,14 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
|
||||||
b.CreateRet(retVal)
|
b.CreateRet(retVal)
|
||||||
}
|
}
|
||||||
case *ssa.RunDefers:
|
case *ssa.RunDefers:
|
||||||
b.createRunDefers()
|
// Note where we're going to put the rundefers block
|
||||||
|
run := b.insertBasicBlock("rundefers.block")
|
||||||
|
b.CreateBr(run)
|
||||||
|
b.runDefersBlock = append(b.runDefersBlock, run)
|
||||||
|
|
||||||
|
after := b.insertBasicBlock("rundefers.after")
|
||||||
|
b.SetInsertPointAtEnd(after)
|
||||||
|
b.afterDefersBlock = append(b.afterDefersBlock, after)
|
||||||
case *ssa.Send:
|
case *ssa.Send:
|
||||||
b.createChanSend(instr)
|
b.createChanSend(instr)
|
||||||
case *ssa.Store:
|
case *ssa.Store:
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче