diff --git a/interp/scan.go b/interp/scan.go index 9def3240..65306562 100644 --- a/interp/scan.go +++ b/interp/scan.go @@ -51,6 +51,8 @@ func (e *evalPackage) hasSideEffects(fn llvm.Value) (*sideEffectResult, error) { return &sideEffectResult{severity: sideEffectNone}, nil case name == "runtime._panic": return &sideEffectResult{severity: sideEffectLimited}, nil + case name == "runtime.typeAssert": + return &sideEffectResult{severity: sideEffectNone}, nil case name == "runtime.interfaceImplements": return &sideEffectResult{severity: sideEffectNone}, nil case name == "runtime.sliceCopy": @@ -118,6 +120,12 @@ func (e *evalPackage) hasSideEffects(fn llvm.Value) (*sideEffectResult, error) { if child.IsDeclaration() { // External function call. Assume only limited side effects // (no affected globals, etc.). + switch child.Name() { + case "runtime.typeAssert": + continue // implemented in interp + case "runtime.interfaceImplements": + continue // implemented in interp + } if e.hasLocalSideEffects(dirtyLocals, inst) { result.updateSeverity(sideEffectLimited) } diff --git a/interp/scan_test.go b/interp/scan_test.go index 9d3e15db..373cec3e 100644 --- a/interp/scan_test.go +++ b/interp/scan_test.go @@ -23,6 +23,8 @@ var scanTestTable = []struct { {"callFunctionPointer", sideEffectAll, []string{"functionPointer"}}, {"getDirtyPointer", sideEffectLimited, nil}, {"storeToPointer", sideEffectLimited, nil}, + {"callTypeAssert", sideEffectNone, nil}, + {"callInterfaceImplements", sideEffectNone, nil}, } func TestScan(t *testing.T) { diff --git a/interp/testdata/scan.ll b/interp/testdata/scan.ll index 946a8a07..bf44750e 100644 --- a/interp/testdata/scan.ll +++ b/interp/testdata/scan.ll @@ -1,6 +1,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64--linux" +%runtime.typecodeID = type { %runtime.typecodeID*, i64 } + +declare i1 @runtime.typeAssert(i64, %runtime.typecodeID*, i8*, i8*) +declare i1 @runtime.interfaceImplements(i64, i8**) + define i64 @returnsConst() { ret i64 0 } @@ -59,3 +64,15 @@ define i64 @callFunctionPointer() { %result = call i64 %fp() ret i64 %result } + +define i1 @callTypeAssert() { + ; Note: parameters are not realistic. + %ok = call i1 @runtime.typeAssert(i64 0, %runtime.typecodeID* null, i8* undef, i8* null) + ret i1 %ok +} + +define i1 @callInterfaceImplements() { + ; Note: parameters are not realistic. + %ok = call i1 @runtime.interfaceImplements(i64 0, i8** null) + ret i1 %ok +}