golang/go

x/tools/go/types: panics on invalid constant

dvyukov opened this issue · 1 comments

The following program crashes with the panic:

package main

import (
    "go/ast"
    "go/parser"
    "go/token"

    _ "golang.org/x/tools/go/gcimporter"
    "golang.org/x/tools/go/types"
)

func main() {
    data := []byte(`
package a
var v = 0>>1.1
`)
    fset := token.NewFileSet()
    f, err := parser.ParseFile(fset, "src.go", data, parser.ParseComments|parser.DeclarationErrors|parser.AllErrors)
    if err != nil {
        return
    }
    _, err = types.Check("pkg", fset, []*ast.File{f})
    if err != nil {
        return
    }
}
panic: 11/10 not an Int

goroutine 1 [running]:
golang.org/x/tools/go/types.(*Checker).handleBailout(0x4c20803c270, 0x4c20802de60)
    src/golang.org/x/tools/go/types/check.go:218 +0xfc
golang.org/x/tools/go/exact.Uint64Val(0x7f4fb20bf128, 0x4c208032ac0, 0x7f4fb20beae8, 0x76e4c0)
    src/golang.org/x/tools/go/exact/exact.go:245 +0x2ef
golang.org/x/tools/go/types.(*Checker).shift(0x4c20803c270, 0x4c208032a40, 0x4c208032a80, 0x15)
    src/golang.org/x/tools/go/types/expr.go:651 +0x186
golang.org/x/tools/go/types.(*Checker).binary(0x4c20803c270, 0x4c208032a40, 0x7f4fb20beef8, 0x4c20801e320, 0x7f4fb20beef8, 0x4c20801e340, 0x15)
    src/golang.org/x/tools/go/types/expr.go:735 +0x14d
golang.org/x/tools/go/types.(*Checker).exprInternal(0x4c20803c270, 0x4c208032a40, 0x7f4fb20bef30, 0x4c20803aa20, 0x0, 0x0, 0x40a100)
    src/golang.org/x/tools/go/types/expr.go:1382 +0x31b6
golang.org/x/tools/go/types.(*Checker).rawExpr(0x4c20803c270, 0x4c208032a40, 0x7f4fb20bef30, 0x4c20803aa20, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:908 +0x80
golang.org/x/tools/go/types.(*Checker).expr(0x4c20803c270, 0x4c208032a40, 0x7f4fb20bef30, 0x4c20803aa20)
    src/golang.org/x/tools/go/types/expr.go:1436 +0x6e
golang.org/x/tools/go/types.(*Checker).varDecl(0x4c20803c270, 0x4c208036af0, 0x4c2080340a0, 0x1, 0x1, 0x0, 0x0, 0x7f4fb20bef30, 0x4c20803aa20)
    src/golang.org/x/tools/go/types/decl.go:158 +0x38e
golang.org/x/tools/go/types.(*Checker).objDecl(0x4c20803c270, 0x7f4fb20bf040, 0x4c208036af0, 0x0, 0x4c20802dd88, 0x0, 0x8)
    src/golang.org/x/tools/go/types/decl.go:81 +0x441
golang.org/x/tools/go/types.(*Checker).packageObjects(0x4c20803c270, 0x4c20800a690, 0x1, 0x1)
    src/golang.org/x/tools/go/types/resolver.go:393 +0x1ff
golang.org/x/tools/go/types.(*Checker).Files(0x4c20803c270, 0x4c20802df30, 0x1, 0x1, 0x0, 0x0)
    src/golang.org/x/tools/go/types/check.go:230 +0x103
golang.org/x/tools/go/types.(*Config).Check(0x4c208032940, 0x6550f0, 0x3, 0x4c208032840, 0x4c20802df30, 0x1, 0x1, 0x0, 0x4c20805ef10, 0x0, ...)
    src/golang.org/x/tools/go/types/api.go:340 +0xbb
golang.org/x/tools/go/types.Check(0x6550f0, 0x3, 0x4c208032840, 0x4c20802df30, 0x1, 0x1, 0x4c208070300, 0x0, 0x0)
    src/golang.org/x/tools/go/types/api.go:42 +0x9b
main.main()
    gotypes.go:22 +0x1e0

Should return an error instead.

on commit af81789

FTR, this also fixed the following gotype crash:

package a
var e,f=f>0>(nil)>>0
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x4fe5a3]

goroutine 1 [running]:
main.checkPkgFiles.func2()
    src/golang.org/x/tools/cmd/gotype/gotype.go:212 +0x92
golang.org/x/tools/go/types.(*Checker).handleBailout(0xc8201021c0, 0xc820113d68)
    src/golang.org/x/tools/go/types/check.go:219 +0xd8
golang.org/x/tools/go/types.representableConst(0x0, 0x0, 0x0, 0x14, 0x0, 0x400)
    src/golang.org/x/tools/go/types/expr.go:187 +0x33
golang.org/x/tools/go/types.(*Checker).shift(0xc8201021c0, 0xc820010940, 0xc8200109c0, 0x15)
    src/golang.org/x/tools/go/types/expr.go:623 +0xeb
golang.org/x/tools/go/types.(*Checker).binary(0xc8201021c0, 0xc820010940, 0x7f3d97ef4918, 0xc82000aaa0, 0x7f3d97ef48a8, 0xc82000aac0, 0x15)
    src/golang.org/x/tools/go/types/expr.go:735 +0x136
golang.org/x/tools/go/types.(*Checker).exprInternal(0xc8201021c0, 0xc820010940, 0x7f3d97ef48e0, 0xc820016c00, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:1382 +0x2ef9
golang.org/x/tools/go/types.(*Checker).rawExpr(0xc8201021c0, 0xc820010940, 0x7f3d97ef48e0, 0xc820016c00, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:908 +0x7d
golang.org/x/tools/go/types.(*Checker).expr(0xc8201021c0, 0xc820010940, 0x7f3d97ef48e0, 0xc820016c00)
    src/golang.org/x/tools/go/types/expr.go:1436 +0x63
golang.org/x/tools/go/types.(*Checker).binary(0xc8201021c0, 0xc820010900, 0x7f3d97ef48e0, 0xc820016bd0, 0x7f3d97ef48e0, 0xc820016c00, 0x29)
    src/golang.org/x/tools/go/types/expr.go:723 +0xa6
golang.org/x/tools/go/types.(*Checker).exprInternal(0xc8201021c0, 0xc820010900, 0x7f3d97ef48e0, 0xc820016c30, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:1382 +0x2ef9
golang.org/x/tools/go/types.(*Checker).rawExpr(0xc8201021c0, 0xc820010900, 0x7f3d97ef48e0, 0xc820016c30, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:908 +0x7d
golang.org/x/tools/go/types.(*Checker).expr(0xc8201021c0, 0xc820010900, 0x7f3d97ef48e0, 0xc820016c30)
    src/golang.org/x/tools/go/types/expr.go:1436 +0x63
golang.org/x/tools/go/types.(*Checker).initVars.func1(0xc820010900, 0x0)
    src/golang.org/x/tools/go/types/assignments.go:208 +0x72
golang.org/x/tools/go/types.unpack(0xc8201111c8, 0x1, 0x1, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/call.go:139 +0x60
golang.org/x/tools/go/types.(*Checker).initVars(0xc8201021c0, 0xc82000e9e0, 0x2, 0x2, 0xc82000ea10, 0x1, 0x1, 0x0)
    src/golang.org/x/tools/go/types/assignments.go:208 +0xcb
golang.org/x/tools/go/types.(*Checker).varDecl(0xc8201021c0, 0xc820015bd0, 0xc82000e9e0, 0x2, 0x2, 0x0, 0x0, 0x7f3d97ef48e0, 0xc820016c30)
    src/golang.org/x/tools/go/types/decl.go:177 +0x2df
golang.org/x/tools/go/types.(*Checker).objDecl(0xc8201021c0, 0x7f3d97ef4a28, 0xc820015bd0, 0x0, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/decl.go:82 +0x483
golang.org/x/tools/go/types.(*Checker).ident(0xc8201021c0, 0xc820010840, 0xc82000aa20, 0x0, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/typexpr.go:37 +0x3a6
golang.org/x/tools/go/types.(*Checker).exprInternal(0xc8201021c0, 0xc820010840, 0x7f3d97ef4870, 0xc82000aa20, 0x0, 0x0, 0x7e)
    src/golang.org/x/tools/go/types/expr.go:952 +0x182
golang.org/x/tools/go/types.(*Checker).rawExpr(0xc8201021c0, 0xc820010840, 0x7f3d97ef4870, 0xc82000aa20, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:908 +0x7d
golang.org/x/tools/go/types.(*Checker).expr(0xc8201021c0, 0xc820010840, 0x7f3d97ef4870, 0xc82000aa20)
    src/golang.org/x/tools/go/types/expr.go:1436 +0x63
golang.org/x/tools/go/types.(*Checker).binary(0xc8201021c0, 0xc820010840, 0x7f3d97ef4870, 0xc82000aa20, 0x7f3d97ef48a8, 0xc82000aa40, 0x29)
    src/golang.org/x/tools/go/types/expr.go:722 +0x71
golang.org/x/tools/go/types.(*Checker).exprInternal(0xc8201021c0, 0xc820010840, 0x7f3d97ef48e0, 0xc820016bd0, 0x0, 0x0, 0x7e)
    src/golang.org/x/tools/go/types/expr.go:1382 +0x2ef9
golang.org/x/tools/go/types.(*Checker).rawExpr(0xc8201021c0, 0xc820010840, 0x7f3d97ef48e0, 0xc820016bd0, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:908 +0x7d
golang.org/x/tools/go/types.(*Checker).expr(0xc8201021c0, 0xc820010840, 0x7f3d97ef48e0, 0xc820016bd0)
    src/golang.org/x/tools/go/types/expr.go:1436 +0x63
golang.org/x/tools/go/types.(*Checker).binary(0xc8201021c0, 0xc820010840, 0x7f3d97ef48e0, 0xc820016bd0, 0x7f3d97ef48e0, 0xc820016c00, 0x29)
    src/golang.org/x/tools/go/types/expr.go:722 +0x71
golang.org/x/tools/go/types.(*Checker).exprInternal(0xc8201021c0, 0xc820010840, 0x7f3d97ef48e0, 0xc820016c30, 0x0, 0x0, 0xc82006c090)
    src/golang.org/x/tools/go/types/expr.go:1382 +0x2ef9
golang.org/x/tools/go/types.(*Checker).rawExpr(0xc8201021c0, 0xc820010840, 0x7f3d97ef48e0, 0xc820016c30, 0x0, 0x0, 0x0)
    src/golang.org/x/tools/go/types/expr.go:908 +0x7d
golang.org/x/tools/go/types.(*Checker).expr(0xc8201021c0, 0xc820010840, 0x7f3d97ef48e0, 0xc820016c30)
    src/golang.org/x/tools/go/types/expr.go:1436 +0x63
golang.org/x/tools/go/types.(*Checker).initVars.func1(0xc820010840, 0x0)
    src/golang.org/x/tools/go/types/assignments.go:208 +0x72
golang.org/x/tools/go/types.unpack(0xc820113a10, 0x1, 0xffffffffffff01, 0x7ac2e0, 0x0, 0xc81ffffaa5)
    src/golang.org/x/tools/go/types/call.go:139 +0x60
golang.org/x/tools/go/types.(*Checker).initVars(0xc8201021c0, 0xc82000e9e0, 0x2, 0x2, 0xc82000ea00, 0x1, 0x1, 0x0)
    src/golang.org/x/tools/go/types/assignments.go:208 +0xcb
golang.org/x/tools/go/types.(*Checker).varDecl(0xc8201021c0, 0xc820015b80, 0xc82000e9e0, 0x2, 0x2, 0x0, 0x0, 0x7f3d97ef48e0, 0xc820016c30)
    src/golang.org/x/tools/go/types/decl.go:177 +0x2df
golang.org/x/tools/go/types.(*Checker).objDecl(0xc8201021c0, 0x7f3d97ef4a28, 0xc820015b80, 0x0, 0xc820113c90, 0x0, 0x8)
    src/golang.org/x/tools/go/types/decl.go:82 +0x483
golang.org/x/tools/go/types.(*Checker).packageObjects(0xc8201021c0, 0xc82000ab40, 0x2, 0x2)
    src/golang.org/x/tools/go/types/resolver.go:400 +0x22a
golang.org/x/tools/go/types.(*Checker).Files(0xc8201021c0, 0xc82006c060, 0x1, 0x1, 0x0, 0x0)
    src/golang.org/x/tools/go/types/check.go:231 +0xfc
golang.org/x/tools/go/types.(*Config).Check(0xc820010800, 0x71ed30, 0x3, 0xc820010780, 0xc82006c060, 0x1, 0x1, 0x0, 0x1, 0x0, ...)
    src/golang.org/x/tools/go/types/api.go:340 +0x248
main.checkPkgFiles(0xc82006c060, 0x1, 0x1)
    src/golang.org/x/tools/cmd/gotype/gotype.go:217 +0x204
main.main()
    src/golang.org/x/tools/cmd/gotype/gotype.go:254 +0x1d9

now it prints:

/tmp/222.go:2:13: invalid operation: shifted operand (nil) (untyped nil value) must be integer
/tmp/222.go:2:13: invalid operation: shifted operand (nil) (untyped nil value) must be integer
/tmp/222.go:2:7: initialization cycle for f
/tmp/222.go:2:7:    f refers to
/tmp/222.go:2:7:    f