From 25b570d7e9dcd62a8554d66ddeea6d074d838c1e Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 8 Jul 2021 11:26:05 +0200 Subject: [PATCH] interp: fix the detection of builtin calls during parsing Avoid shortcuts, and apply regular scoping rules for symbol resolution when checking for builtin calls. Fixes #1173. --- _test/issue-1173.go | 10 ++++++++++ interp/cfg.go | 5 ++--- interp/type.go | 11 ++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 _test/issue-1173.go diff --git a/_test/issue-1173.go b/_test/issue-1173.go new file mode 100644 index 000000000..3747f3dc3 --- /dev/null +++ b/_test/issue-1173.go @@ -0,0 +1,10 @@ +package main + +var real = func() { println("Hello") } + +func main() { + real() +} + +// Output: +// Hello diff --git a/interp/cfg.go b/interp/cfg.go index 55d21eb3d..a45ec3153 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -864,7 +864,7 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) { case callExpr: wireChild(n) switch { - case interp.isBuiltinCall(n): + case isBuiltinCall(n, sc): c0 := n.child[0] bname := c0.ident err = check.builtin(bname, n, n.child[1:], n.action == aCallSlice) @@ -1260,11 +1260,10 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) { } } // Found symbol, populate node info - n.typ, n.findex, n.level = sym.typ, sym.index, level + n.sym, n.typ, n.findex, n.level = sym, sym.typ, sym.index, level if n.findex < 0 { n.val = sym.node } else { - n.sym = sym switch { case sym.kind == constSym && sym.rval.IsValid(): n.rval = sym.rval diff --git a/interp/type.go b/interp/type.go index f06d5cbb4..797dc2535 100644 --- a/interp/type.go +++ b/interp/type.go @@ -303,7 +303,7 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) { t = dt case callExpr: - if interp.isBuiltinCall(n) { + if isBuiltinCall(n, sc) { // Builtin types are special and may depend from their input arguments. t.cat = builtinT switch n.child[0].ident { @@ -675,11 +675,16 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) { return t, err } -func (interp *Interpreter) isBuiltinCall(n *node) bool { +func isBuiltinCall(n *node, sc *scope) bool { if n.kind != callExpr { return false } - s := interp.universe.sym[n.child[0].ident] + s := n.child[0].sym + if s == nil { + if sym, _, found := sc.lookup(n.child[0].ident); found { + s = sym + } + } return s != nil && s.kind == bltnSym }