feat: add star expression type checking

This adds type checking to StarExpr. This also fixes a bug in assignment where the symbol type was updated but not the scope type associated with it.
This commit is contained in:
Nicholas Wiersma
2020-08-21 10:56:03 +02:00
committed by GitHub
parent 3640f2f820
commit 358a57b4b9
3 changed files with 27 additions and 0 deletions

View File

@@ -518,6 +518,11 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
if updateSym {
sym.typ = dest.typ
sym.rval = src.rval
// As we are updating the sym type, we need to update the sc.type
// when the sym has an index.
if sym.index >= 0 {
sc.types[sym.index] = sym.typ.frameType()
}
}
n.findex = dest.findex
n.level = dest.level
@@ -1554,6 +1559,12 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
default:
// dereference expression
wireChild(n)
err = check.starExpr(n.child[0])
if err != nil {
break
}
if c0 := n.child[0]; c0.typ.cat == valueT {
n.typ = &itype{cat: valueT, rtype: c0.typ.rtype.Elem()}
} else {

View File

@@ -70,6 +70,14 @@ func TestEvalArithmetic(t *testing.T) {
})
}
func TestEvalStar(t *testing.T) {
i := interp.New(interp.Options{})
runTests(t, i, []testCase{
{src: `a := &struct{A int}{1}; b := *a`, res: "{1}"},
{src: `a := struct{A int}{1}; b := *a`, err: "1:57: invalid operation: cannot indirect \"a\""},
})
}
func TestEvalAssign(t *testing.T) {
i := interp.New(interp.Options{})
runTests(t, i, []testCase{

View File

@@ -106,6 +106,14 @@ func (check typecheck) addressExpr(n *node) error {
return nil
}
// starExpr type checks a star expression on a variable.
func (check typecheck) starExpr(n *node) error {
if n.typ.TypeOf().Kind() != reflect.Ptr {
return n.cfgErrorf("invalid operation: cannot indirect %q", n.name())
}
return nil
}
var unaryOpPredicates = opPredicates{
aPos: isNumber,
aNeg: isNumber,