Skip to content

Commit

Permalink
fix: dont allow calling init
Browse files Browse the repository at this point in the history
  • Loading branch information
nrwiersma committed Jul 9, 2020
1 parent 98eacf3 commit 3c6df50
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 30 deletions.
12 changes: 12 additions & 0 deletions _test/init1.go
@@ -0,0 +1,12 @@
package main

func init() {
println("here")
}

func main() {
init()
}

// Error:
// _test/init1.go:8:2: undefined: init
14 changes: 9 additions & 5 deletions interp/cfg.go
Expand Up @@ -1153,11 +1153,11 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
n.types = sc.types
sc = sc.pop()
funcName := n.child[1].ident
if !isMethod(n) {
interp.scopes[pkgID].sym[funcName].index = -1 // to force value to n.val
interp.scopes[pkgID].sym[funcName].typ = n.typ
interp.scopes[pkgID].sym[funcName].kind = funcSym
interp.scopes[pkgID].sym[funcName].node = n
if sym := sc.sym[funcName]; !isMethod(n) && sym != nil {
sym.index = -1 // to force value to n.val
sym.typ = n.typ
sym.kind = funcSym
sym.node = n
}

case funcLit:
Expand All @@ -1172,6 +1172,10 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
if isKey(n) || isNewDefine(n, sc) {
break
}
if n.anc.kind == funcDecl && n.anc.child[1] == n {
// Dont process a function name identExpr.
break
}

sym, level, found := sc.lookup(n.ident)
if !found {
Expand Down
51 changes: 26 additions & 25 deletions interp/gta.go
Expand Up @@ -138,11 +138,13 @@ func (interp *Interpreter) gta(root *node, rpath, pkgID string) ([]*node, error)
if n.typ, err = nodeType(interp, sc, n.child[2]); err != nil {
return false
}
if isMethod(n) {
ident := n.child[1].ident
switch {
case isMethod(n):
// TODO(mpl): redeclaration detection
// Add a method symbol in the receiver type name space
var rcvrtype *itype
n.ident = n.child[1].ident
n.ident = ident
rcvr := n.child[0].child[0]
rtn := rcvr.lastChild()
typeName := rtn.ident
Expand All @@ -167,33 +169,32 @@ func (interp *Interpreter) gta(root *node, rpath, pkgID string) ([]*node, error)
}
rcvrtype.method = append(rcvrtype.method, n)
n.child[0].child[0].lastChild().typ = rcvrtype
} else {
ident := n.child[1].ident
case ident == "init":
// TODO(mpl): use constant instead of hardcoded string?
if ident != "init" {
asImportName := filepath.Join(ident, baseName)
if _, exists := sc.sym[asImportName]; exists {
// redeclaration error
// TODO(mpl): improve error with position of previous declaration.
err = n.cfgErrorf("%s redeclared in this block", ident)
return false
}
sym, exists := sc.sym[ident]
if exists {
// Make sure the symbol we found seems to be about another node, before calling
// it a redeclaration.
if sym.typ.isComplete() {
// TODO(mpl): this check might be too permissive?
if sym.kind != funcSym || sym.typ.cat != n.typ.cat || sym.node != n || sym.index != -1 {
// redeclaration error
// TODO(mpl): improve error with position of previous declaration.
err = n.cfgErrorf("%s redeclared in this block", ident)
return false
}
// init functions do not get declared as per the Go spec.
default:
asImportName := filepath.Join(ident, baseName)
if _, exists := sc.sym[asImportName]; exists {
// redeclaration error
// TODO(mpl): improve error with position of previous declaration.
err = n.cfgErrorf("%s redeclared in this block", ident)
return false
}
sym, exists := sc.sym[ident]
if exists {
// Make sure the symbol we found seems to be about another node, before calling
// it a redeclaration.
if sym.typ.isComplete() {
// TODO(mpl): this check might be too permissive?
if sym.kind != funcSym || sym.typ.cat != n.typ.cat || sym.node != n || sym.index != -1 {
// redeclaration error
// TODO(mpl): improve error with position of previous declaration.
err = n.cfgErrorf("%s redeclared in this block", ident)
return false
}
}
}
// Add a function symbol in the package name space
// Add a function symbol in the package name space except for init
sc.sym[n.child[1].ident] = &symbol{kind: funcSym, typ: n.typ, node: n, index: -1}
}
if !n.typ.isComplete() {
Expand Down
1 change: 1 addition & 0 deletions interp/interp_consistent_test.go
Expand Up @@ -45,6 +45,7 @@ func TestInterpConsistencyBuild(t *testing.T) {
file.Name() == "fun22.go" || // expect error
file.Name() == "if2.go" || // expect error
file.Name() == "import6.go" || // expect error
file.Name() == "init1.go" || // expect error
file.Name() == "io0.go" || // use random number
file.Name() == "op1.go" || // expect error
file.Name() == "op7.go" || // expect error
Expand Down

0 comments on commit 3c6df50

Please sign in to comment.