interp: better support interface operations
This commit teaches the interp scanner that supported interface operations (type assertions, interface assertions) are supported. This fixes a problem with math/rand in Go 1.14.
Этот коммит содержится в:
родитель
5133604b51
коммит
25fcf3e18e
3 изменённых файлов: 27 добавлений и 0 удалений
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
17
interp/testdata/scan.ll
предоставленный
17
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
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче