golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.12k stars 17.68k forks source link

go.tools/go/pointer: panic when executing oracle peer mode. #9002

Closed DanielMorsing closed 9 years ago

DanielMorsing commented 10 years ago
The following program causes the pointer analysis to fail:

package main

func main() {
    ch := make(chan *int)
    <-ch
    for range ch {
    }
}

Querying for peers at <-ch causes a panic.

Panic and pointer analysis log:

==== Starting analysis
==== Generating constraints
    create n0 invalid type for (zero)
    create n1 interface{} for panic
    create n2 func() for root.targets
    root call to main.init:
    create n3 func() for main.init
    ---- makeFunctionObject main.init
    create n4 func() for func.cgnode
    ----
    globalobj[main.init] = n4
    addr n3 <- {&n4}
    val[init] = n3  (*ssa.Function)
    copy n2 <- n3
    root call to main.main:
    create n5 func() for main.main
    ---- makeFunctionObject main.main
    create n6 func() for func.cgnode
    ----
    globalobj[main.main] = n6
    addr n5 <- {&n6}
    val[main] = n5  (*ssa.Function)
    copy n2 <- n5

==== Generating constraints for cg4:main.init, shared contour
# Name: main.init
# Package: main
# Synthetic: package initializer
func init():
0:                                                                entry P:0 S:2
    t0 = *init$guard                                                   bool
    if t0 goto 2 else 1
1:                                                           init.start P:1 S:1
    *init$guard = true:bool
    jump 2
2:          ao: exit 2
                                                  init.done P:2 S:0
    return

; Creating nodes for local values
    create n7 bool for t0
    val[t0] = n7  (*ssa.UnOp)
; t0 = *init$guard
    create n8 bool for global
    globalobj[main.init$guard] = n8
    copy n7 <- n8
; if t0 goto 2 else 1
; *init$guard = true:bool
    create n9 bool for true:bool
    globalobj[true:bool] = n0
    val[true:bool] = n9  (*ssa.Const)
    copy n8 <- n9
; jump 2
; return

==== Generating constraints for cg6:main.main, shared contour
# Name: main.main
# Package: main
# Location: /home/daniel/src/test/te.go:3:6
func main():
0:                                                                entry P:0 S:1
    t0 = make chan *int 0:int                                     chan *int
    ; *ast.CallExpr @ 4:8 is t0
    ; var ch chan *int @ 4:2 is t0
    ; var ch chan *int @ 5:4 is t0
    t1 = <-t0                                                          *int
    ; *ast.UnaryExpr @ 5:2 is t1
    ; var ch chan *int @ 6:12 is t0
    jump 1
1:                                                       rangechan.loop P:2 S:2
    t2 = <-t0,ok                                          (k *int, ok bool)
    t3 = extract t2 #1                                                 bool
    if t3 goto 1 else 2
2:                                                       rangechan.done P:1 S:0
    return

; Creating nodes for local values
    create n10 chan *int for t0
    val[t0] = n10  (*ssa.MakeChan)
    create n11 chan *int for query
    copy n11 <- n10
    create n12 *int for t1
    val[t1] = n12  (*ssa.UnOp)
    create n13 *int for t2#0
    create n14 bool for t2#1
    val[t2] = n13  (*ssa.UnOp)
    create n15 bool for t3
    val[t3] = n15  (*ssa.Extract)
; t0 = make chan *int 0:int
    create n16 *int for makechan
    localobj[t0] = n16
    addr n10 <- {&n16}
; ; *ast.CallExpr @ 4:8 is t0
; ; var ch chan *int @ 4:2 is t0
; ; var ch chan *int @ 5:4 is t0
; t1 = <-t0
    copy n12 <- n16
; ; *ast.UnaryExpr @ 5:2 is t1
; ; var ch chan *int @ 6:12 is t0
; jump 1
; t2 = <-t0,ok
    copy n13 <- n16
    copy n14 <- n17
; t3 = extract t2 #1
    copy n15 <- n14
; if t3 goto 1 else 2
; return
# constraints:  12
          9  (75%)  *pointer.copyConstraint
          3  (25%)  *pointer.addrConstraint
# nodes:    17
# ptsets:   17

==== Renumbering

Renumbering nodes to improve density:
(5 object nodes of 17 total)
    n0 -> n0
    n1 -> n5
    n2 -> n6
    n3 -> n7
    n4 -> n1
    n5 -> n8
    n6 -> n2
    n7 -> n9
    n8 -> n3
    n9 -> n10
    n10 -> n11
    n11 -> n12
    n12 -> n13
    n13 -> n14
    n14 -> n15
    n15 -> n16
    n16 -> n4
Internal panic in pointer analysis:
/home/daniel/src/goprj/src/code.google.com/p/go.tools/go/pointer/analysis.go:222
(0x6ca1bc)
    func.001: debug.PrintStack()
/home/daniel/src/godev/src/runtime/asm_amd64.s:401 (0x43dff5)
    call16: CALLFN(·call16, 16)
/home/daniel/src/godev/src/runtime/panic.go:387 (0x416768)
    gopanic: reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/home/daniel/src/godev/src/runtime/panic.go:12 (0x4158fe)
    panicindex: panic(indexError)
/home/daniel/src/goprj/src/code.google.com/p/go.tools/go/pointer/constraint.go:56
(0x698fd5)
    (*copyConstraint).renumber: c.src = mapping[c.src]
/home/daniel/src/goprj/src/code.google.com/p/go.tools/go/pointer/opt.go:113 (0x6b1aba)
    (*analysis).renumber: c.renumber(renumbering)
/home/daniel/src/goprj/src/code.google.com/p/go.tools/go/pointer/analysis.go:291
(0x694bb5)
    Analyze: a.renumber()
/home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/oracle.go:477 (0x4adfb4)
    ptrAnalysis: result, err := pointer.Analyze(&o.ptaConfig)
/home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/peers.go:73 (0x4af2ab)
    peers: ptares := ptrAnalysis(o)
/home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/oracle.go:419 (0x4ad5fb)
    (*Oracle).query: res.q, err = minfo.impl(o, qpos)
/home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/oracle.go:406 (0x4ad4b3)
    (*Oracle).Query: return o.query(minfo, qpos)
/home/daniel/src/goprj/src/github.com/DanielMorsing/ao/main.go:84 (0x401a0d)
    main: res, err := oracl.Query(mode, qp)
/home/daniel/src/godev/src/runtime/proc.go:63 (0x4182b3)
    main: main_main()
/home/daniel/src/godev/src/runtime/proc.c:1651 (0x435d00)
    goexit: runtime·goexit(void)
panic: internal error in pointer analysis: runtime error: index out of range (please
report this bug)

goroutine 1 [running]:
code.google.com/p/go.tools/oracle.ptrAnalysis(0xc20805cd20, 0x0)
    /home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/oracle.go:479 +0x79
code.google.com/p/go.tools/oracle.peers(0xc20805cd20, 0xc20802a940, 0x0, 0x0, 0x0, 0x0)
    /home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/peers.go:73 +0x90b
code.google.com/p/go.tools/oracle.(*Oracle).query(0xc20805cd20, 0xa6eca0, 0xc20802a940,
0x0, 0x0, 0x0)
    /home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/oracle.go:419 +0x10b
code.google.com/p/go.tools/oracle.(*Oracle).Query(0xc20805cd20, 0xc20800afe0, 0x5,
0xc20802a940, 0xc20802a940, 0x0, 0x0)
    /home/daniel/src/goprj/src/code.google.com/p/go.tools/oracle/oracle.go:406 +0x193
main.main()
    /home/daniel/src/goprj/src/github.com/DanielMorsing/ao/main.go:84 +0xd5d

Looks like n17 is used without it being created, causing a panic during renumbering.
ianlancetaylor commented 10 years ago

Comment 1:

Labels changed: added release-none.

gopherbot commented 10 years ago

Comment 2:

CL https://golang.org/cl/163350043 mentions this issue.
adonovan commented 10 years ago

Comment 3:

This issue was closed by revision golang/tools@11451553df90dae7672c8fe6e1e869263bff484.

Status changed to Fixed.