| // Copyright 2026 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package inline |
| |
| import ( |
| "go/ast" |
| "go/parser" |
| "go/token" |
| "go/types" |
| "testing" |
| ) |
| |
| // TestEscapeIllTyped checks that escape analysis does not panic on |
| // ill-typed AST/types.Info (golang/go#75236), including nil TypeOf for |
| // selector/index bases and non-lvalue operands of & / assignment LHS. |
| func TestEscapeIllTyped(t *testing.T) { |
| const src = ` |
| package p |
| func f() int { |
| var x Undeclared |
| _ = &x.S.F // SelectorExpr with info.TypeOf(x.S) == nil |
| _ = &x.A[0] // IndexExpr with info.TypeOf(x.A) == nil |
| _ = &f() // non-lvalue operand of & (hits default case in lvalue) |
| f() = 1 // non-lvalue LHS of assignment (hits default case in lvalue) |
| return 0 |
| } |
| ` |
| fset := token.NewFileSet() |
| file, err := parser.ParseFile(fset, "p.go", src, 0) |
| if err != nil { |
| t.Fatal(err) |
| } |
| info := &types.Info{ |
| Defs: make(map[*ast.Ident]types.Object), |
| Uses: make(map[*ast.Ident]types.Object), |
| Types: make(map[ast.Expr]types.TypeAndValue), |
| } |
| conf := &types.Config{Error: func(error) {}} |
| _, _ = conf.Check("p", fset, []*ast.File{file}, info) |
| // Must not panic on ill-typed AST/types.Info. |
| escape(info, file.Decls[0], func(*types.Var, bool) {}) |
| } |