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.
This commit is contained in:
Marc Vertes
2021-07-08 11:26:05 +02:00
committed by GitHub
parent 297b40d526
commit 25b570d7e9
3 changed files with 20 additions and 6 deletions

10
_test/issue-1173.go Normal file
View File

@@ -0,0 +1,10 @@
package main
var real = func() { println("Hello") }
func main() {
real()
}
// Output:
// Hello

View File

@@ -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

View File

@@ -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
}