From feb2b4715b06a5a08d7a5f953e0c60d7a75d8f9a Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 4 Nov 2019 12:45:18 +0100 Subject: [PATCH] interp: fix scanning declarations Declarations would enter an infinite loop when trying to loop over basic blocks. That was probably an undefined operation, but still somehow didn't crash the compiler. Make sure that scanning declarations works as expected. --- interp/scan.go | 3 +++ interp/scan_test.go | 1 + interp/testdata/scan.ll | 2 ++ 3 files changed, 6 insertions(+) diff --git a/interp/scan.go b/interp/scan.go index a96bcb58..add2ca3b 100644 --- a/interp/scan.go +++ b/interp/scan.go @@ -57,6 +57,9 @@ func (e *Eval) hasSideEffects(fn llvm.Value) *sideEffectResult { case "llvm.dbg.value": return &sideEffectResult{severity: sideEffectNone} } + if fn.IsDeclaration() { + return &sideEffectResult{severity: sideEffectLimited} + } if e.sideEffectFuncs == nil { e.sideEffectFuncs = make(map[llvm.Value]*sideEffectResult) } diff --git a/interp/scan_test.go b/interp/scan_test.go index 226373ce..229b12ec 100644 --- a/interp/scan_test.go +++ b/interp/scan_test.go @@ -21,6 +21,7 @@ var scanTestTable = []struct { {"readCleanGlobal", sideEffectNone, []string{"cleanGlobalInt"}}, {"readDirtyGlobal", sideEffectLimited, []string{"dirtyGlobalInt"}}, {"callFunctionPointer", sideEffectAll, []string{"functionPointer"}}, + {"getDirtyPointer", sideEffectLimited, nil}, } func TestScan(t *testing.T) { diff --git a/interp/testdata/scan.ll b/interp/testdata/scan.ll index 33ae3001..35246419 100644 --- a/interp/testdata/scan.ll +++ b/interp/testdata/scan.ll @@ -45,6 +45,8 @@ define i64 @readDirtyGlobal() { ret i64 %global } +declare i64* @getDirtyPointer() + @functionPointer = global i64()* null define i64 @callFunctionPointer() { %fp = load i64()*, i64()** @functionPointer