From cfc1a66e8dca16fecceda96c03ac784f322ad0bf Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 7 Mar 2019 15:05:25 +0100 Subject: [PATCH] interp: use correct initialization order on panic() calls Whenever interp hits an unreachable instruction, it bails out at that point. However, it used to insert new instructions at the bottom with the old init calls still at the top. So when a panic() happened in a non-main package, the last packages to init would actually be called first. This commit fixes this by setting the insert point at the top of runtime.initAll before starting interpretation, so the initialization order is still correct when a panic() happens during init. --- interp/interp.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/interp/interp.go b/interp/interp.go index 7328170a..aa8507c9 100644 --- a/interp/interp.go +++ b/interp/interp.go @@ -42,10 +42,19 @@ func Run(mod llvm.Module, targetData llvm.TargetData, debug bool) error { initAll := mod.NamedFunction(name) bb := initAll.EntryBasicBlock() - e.builder.SetInsertPointBefore(bb.LastInstruction()) + // Create a dummy alloca in the entry block that we can set the insert point + // to. This is necessary because otherwise we might be removing the + // instruction (init call) that we are removing after successful + // interpretation. + e.builder.SetInsertPointBefore(bb.FirstInstruction()) + dummy := e.builder.CreateAlloca(e.Mod.Context().Int8Type(), "dummy") + e.builder.SetInsertPointBefore(dummy) e.builder.SetInstDebugLocation(bb.FirstInstruction()) var initCalls []llvm.Value for inst := bb.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) { + if inst == dummy { + continue + } if !inst.IsAReturnInst().IsNil() { break // ret void }