diff --git a/interp/interp.go b/interp/interp.go index d3976ef7..574fe01a 100644 --- a/interp/interp.go +++ b/interp/interp.go @@ -110,17 +110,19 @@ func Run(mod llvm.Module, debug bool) error { fmt.Fprintln(os.Stderr, "call:", fn.Name()) } _, mem, callErr := r.run(r.getFunction(fn), nil, nil, " ") + call.EraseFromParentAsInstruction() if callErr != nil { if isRecoverableError(callErr.Err) { if r.debug { fmt.Fprintln(os.Stderr, "not interpreting", r.pkgName, "because of error:", callErr.Error()) } mem.revert() + i8undef := llvm.Undef(r.i8ptrType) + r.builder.CreateCall(fn, []llvm.Value{i8undef, i8undef}, "") continue } return callErr } - call.EraseFromParentAsInstruction() for index, obj := range mem.objects { r.objects[index] = obj } diff --git a/interp/interp_test.go b/interp/interp_test.go index 50af8af6..9702cb83 100644 --- a/interp/interp_test.go +++ b/interp/interp_test.go @@ -17,6 +17,7 @@ func TestInterp(t *testing.T) { "slice-copy", "consteval", "interface", + "revert", } { name := name // make tc local to this closure t.Run(name, func(t *testing.T) { diff --git a/interp/testdata/revert.ll b/interp/testdata/revert.ll new file mode 100644 index 00000000..49354ce9 --- /dev/null +++ b/interp/testdata/revert.ll @@ -0,0 +1,21 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64--linux" + +declare void @externalCall(i64) + +define void @runtime.initAll() unnamed_addr { +entry: + call void @foo.init(i8* undef, i8* undef) + call void @main.init(i8* undef, i8* undef) + ret void +} + +define internal void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr { + unreachable ; this triggers a revert of @foo.init. +} + +define internal void @main.init(i8* %context, i8* %parentHandle) unnamed_addr { +entry: + call void @externalCall(i64 3) + ret void +} diff --git a/interp/testdata/revert.out.ll b/interp/testdata/revert.out.ll new file mode 100644 index 00000000..7309439f --- /dev/null +++ b/interp/testdata/revert.out.ll @@ -0,0 +1,15 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64--linux" + +declare void @externalCall(i64) local_unnamed_addr + +define void @runtime.initAll() unnamed_addr { +entry: + call fastcc void @foo.init(i8* undef, i8* undef) + call void @externalCall(i64 3) + ret void +} + +define internal fastcc void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr { + unreachable +}