fix: define a correct zero value for an not initialized interface{}

This commit is contained in:
Marc Vertes
2020-02-04 18:04:05 +01:00
committed by GitHub
parent 4fd6a2dc56
commit 23dfef0ac8
3 changed files with 33 additions and 3 deletions

12
_test/interface19.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import "fmt"
var I interface{}
func main() {
fmt.Printf("%T %v\n", I, I)
}
// Output:
// <nil> <nil>

View File

@@ -1443,8 +1443,14 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
}
}
for _, c := range n.child[:l] {
index := sc.add(n.typ)
sc.sym[c.ident] = &symbol{index: index, kind: varSym, typ: n.typ}
var index int
if sc.global {
// Global object allocation is already performed in GTA.
index = sc.sym[c.ident].index
} else {
index = sc.add(n.typ)
sc.sym[c.ident] = &symbol{index: index, kind: varSym, typ: n.typ}
}
c.typ = n.typ
c.findex = index
}

View File

@@ -180,11 +180,23 @@ func genValueInterface(n *node) func(*frame) reflect.Value {
}
}
func zeroInterfaceValue() reflect.Value {
n := &node{kind: basicLit, typ: &itype{cat: nilT, untyped: true}}
v := reflect.New(reflect.TypeOf((*interface{})(nil)).Elem()).Elem()
return reflect.ValueOf(valueInterface{n, v})
}
func genValueInterfaceValue(n *node) func(*frame) reflect.Value {
value := genValue(n)
return func(f *frame) reflect.Value {
return value(f).Interface().(valueInterface).value
v := value(f)
if v.Interface().(valueInterface).node == nil {
// Uninitialized interface value, set it to a correct zero value.
v.Set(zeroInterfaceValue())
v = value(f)
}
return v.Interface().(valueInterface).value
}
}