From e9772760448a2186e89caeb69f60a94586d07bc5 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 4 Nov 2019 12:47:22 +0100 Subject: [PATCH] interp: fix "todo: store" panic This is really just a simple workaround. When such an instruction is encountered, it will just fall back to marking the entire function as having side effects. Ideally it should trace all affected instructions and check if they would have any side effects, but this at least fixes a number of compile errors. This commit gets the following packages to compile: * context * database/sql/driver * image/jpeg * image/png --- interp/scan.go | 11 +++++++---- interp/scan_test.go | 1 + interp/testdata/scan.ll | 6 ++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/interp/scan.go b/interp/scan.go index add2ca3b..b8c68117 100644 --- a/interp/scan.go +++ b/interp/scan.go @@ -193,10 +193,13 @@ func (e *Eval) hasLocalSideEffects(dirtyLocals map[llvm.Value]struct{}, inst llv // Already handled in (*Eval).hasSideEffects. continue } - // But a store might also store to an alloca, in which case all uses - // of the alloca (possibly indirect through a GEP, bitcast, etc.) - // must be marked dirty. - panic("todo: store") + // This store might affect all kinds of values. While it is + // certainly possible to traverse through all of them, the easiest + // option right now is to just assume the worst and say that this + // function has side effects. + // TODO: traverse through all stores and mark all relevant allocas / + // globals dirty. + return true default: // All instructions that take 0 or more operands (1 or more if it // was a use) and produce a result. diff --git a/interp/scan_test.go b/interp/scan_test.go index 229b12ec..2150f108 100644 --- a/interp/scan_test.go +++ b/interp/scan_test.go @@ -22,6 +22,7 @@ var scanTestTable = []struct { {"readDirtyGlobal", sideEffectLimited, []string{"dirtyGlobalInt"}}, {"callFunctionPointer", sideEffectAll, []string{"functionPointer"}}, {"getDirtyPointer", sideEffectLimited, nil}, + {"storeToPointer", sideEffectLimited, nil}, } func TestScan(t *testing.T) { diff --git a/interp/testdata/scan.ll b/interp/testdata/scan.ll index 35246419..946a8a07 100644 --- a/interp/testdata/scan.ll +++ b/interp/testdata/scan.ll @@ -47,6 +47,12 @@ define i64 @readDirtyGlobal() { declare i64* @getDirtyPointer() +define void @storeToPointer() { + %ptr = call i64* @getDirtyPointer() + store i64 3, i64* %ptr + ret void +} + @functionPointer = global i64()* null define i64 @callFunctionPointer() { %fp = load i64()*, i64()** @functionPointer