# Test of -whylive flag.
# The -whylive argument must be live.
!deadcode -whylive=example.com.d example.com
want "function example.com.d is dead code"
# A fully static path is preferred, even if longer.
deadcode -whylive=example.com.c example.com
want " example.com.main"
want " static@L0004 --> example.com.a"
want " static@L0009 --> example.com.b"
want " static@L0012 --> example.com.c"
# Dynamic edges are followed if necessary.
# (Note that main is preferred over init.)
deadcode -whylive=example.com.f example.com
want " example.com.main"
want "dynamic@L0006 --> example.com.e"
want " static@L0017 --> example.com.f"
# Degenerate case where target is itself a root.
!deadcode -whylive=example.com.main example.com
want "example.com.main is a root"
# Test of path through (*T).m method wrapper.
deadcode -whylive=example.com/p.live example.com/p
want " example.com/p.main"
want "static@L0006 --> example.com/p.E.Error"
want "static@L0010 --> example.com/p.live"
# Test of path through (I).m interface method wrapper (thunk).
deadcode -whylive=example.com/q.live example.com/q
want " example.com/q.main"
want "static@L0006 --> example.com/q.E.Error"
want "static@L0010 --> example.com/q.live"
# Test of path through synthetic package initializer,
# a declared package initializer, and its anonymous function.
deadcode -whylive=example.com/q.live2 example.com/q
want " example.com/q.init"
want "static@L0000 --> example.com/q.init#1"
want "static@L0016 --> example.com/q.init#1$1"
want "static@L0015 --> example.com/q.live2"
# Test of path through synthetic package initializer,
# and a global var initializer.
deadcode -whylive=example.com/r.live example.com/r
want " example.com/r.init"
want "static@L0007 --> example.com/r.init$1"
want "static@L0006 --> example.com/r.live"
-- go.mod --
module example.com
go 1.18
-- main.go --
package main
func main() {
a()
println(c, e) // c, e are address-taken
(func ())(nil)() // potential dynamic call to c, e
}
func a() {
b()
}
func b() {
c()
}
func c()
func d()
func e() {
f()
}
func f()
func init() {
(func ())(nil)() // potential dynamic call to c, e
}
-- p/p.go --
package main
func main() {
f := (*E).Error
var e E
f(&e)
}
type E int
func (E) Error() string { return live() }
func live() string
-- q/q.go --
package main
func main() {
f := error.Error
var e E
f(e)
}
type E int
func (E) Error() string { return live() }
func live() string
func init() {
f := func() { live2() }
f()
}
func live2()
-- r/r.go --
package main
func main() {}
var x = func() int {
return live()
}()
func live() int