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.
Этот коммит содержится в:
Ayke van Laethem 2019-11-04 12:45:18 +01:00 коммит произвёл Ron Evans
родитель 3b0ed63c29
коммит feb2b4715b
3 изменённых файлов: 6 добавлений и 0 удалений

Просмотреть файл

@ -57,6 +57,9 @@ func (e *Eval) hasSideEffects(fn llvm.Value) *sideEffectResult {
case "llvm.dbg.value": case "llvm.dbg.value":
return &sideEffectResult{severity: sideEffectNone} return &sideEffectResult{severity: sideEffectNone}
} }
if fn.IsDeclaration() {
return &sideEffectResult{severity: sideEffectLimited}
}
if e.sideEffectFuncs == nil { if e.sideEffectFuncs == nil {
e.sideEffectFuncs = make(map[llvm.Value]*sideEffectResult) e.sideEffectFuncs = make(map[llvm.Value]*sideEffectResult)
} }

Просмотреть файл

@ -21,6 +21,7 @@ var scanTestTable = []struct {
{"readCleanGlobal", sideEffectNone, []string{"cleanGlobalInt"}}, {"readCleanGlobal", sideEffectNone, []string{"cleanGlobalInt"}},
{"readDirtyGlobal", sideEffectLimited, []string{"dirtyGlobalInt"}}, {"readDirtyGlobal", sideEffectLimited, []string{"dirtyGlobalInt"}},
{"callFunctionPointer", sideEffectAll, []string{"functionPointer"}}, {"callFunctionPointer", sideEffectAll, []string{"functionPointer"}},
{"getDirtyPointer", sideEffectLimited, nil},
} }
func TestScan(t *testing.T) { func TestScan(t *testing.T) {

2
interp/testdata/scan.ll предоставленный
Просмотреть файл

@ -45,6 +45,8 @@ define i64 @readDirtyGlobal() {
ret i64 %global ret i64 %global
} }
declare i64* @getDirtyPointer()
@functionPointer = global i64()* null @functionPointer = global i64()* null
define i64 @callFunctionPointer() { define i64 @callFunctionPointer() {
%fp = load i64()*, i64()** @functionPointer %fp = load i64()*, i64()** @functionPointer