Skip to content

Commit

Permalink
interp: fix array size definition in case of forward declared constant
Browse files Browse the repository at this point in the history
In type.go, the symbol lookup on constant id was not performed. Handle
the ident kind explicitely to allow that.

Fixes #911.
  • Loading branch information
mvertes authored Oct 21, 2020
1 parent c0eaab0 commit 22c63b2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 19 deletions.
12 changes: 12 additions & 0 deletions _test/a44.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

var a = [max]int{}

const max = 32

func main() {
println(len(a))
}

// Output:
// 32
41 changes: 22 additions & 19 deletions interp/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,30 +185,33 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
} else {
t.size = int(v.Int())
}
case n.child[0].kind == ellipsisExpr:
case c0.kind == ellipsisExpr:
// [...]T expression, get size from the length of composite array.
t.size = arrayTypeLen(n.anc)
default:
if sym, _, ok := sc.lookup(c0.ident); ok {
// Size is defined by a symbol which must be a constant integer.
if sym.kind != constSym {
return nil, c0.cfgErrorf("non-constant array bound %q", c0.ident)
}
if sym.typ == nil || sym.typ.cat != intT {
t.incomplete = true
break
}
if v, ok := sym.rval.Interface().(int); ok {
t.size = v
break
}
if c, ok := sym.rval.Interface().(constant.Value); ok {
t.size = constToInt(c)
break
}
case c0.kind == identExpr:
sym, _, ok := sc.lookup(c0.ident)
if !ok {
t.incomplete = true
break
}
// Size is defined by a symbol which must be a constant integer.
if sym.kind != constSym {
return nil, c0.cfgErrorf("non-constant array bound %q", c0.ident)
}
if sym.typ == nil || sym.typ.cat != intT {
t.incomplete = true
break
}
if v, ok := sym.rval.Interface().(int); ok {
t.size = v
break
}
if c, ok := sym.rval.Interface().(constant.Value); ok {
t.size = constToInt(c)
break
}
t.incomplete = true
default:
// Size is defined by a numeric constant expression.
if _, err = interp.cfg(c0, sc.pkgID); err != nil {
return nil, err
Expand Down

0 comments on commit 22c63b2

Please sign in to comment.