5 func final1a(x *int) int {
6 print(x) // @pointsto new@newint:10
10 func final1b(x *bool) {
14 func runtimeSetFinalizer1() {
15 x := new(int) // @line newint
16 runtime.SetFinalizer(x, final1a) // ok: final1a's result is ignored
17 runtime.SetFinalizer(x, final1b) // param type mismatch: no effect
20 // @calls main.runtimeSetFinalizer1 -> main.final1a
21 // @calls main.runtimeSetFinalizer1 -> main.final1b
23 func final2a(x *bool) {
24 print(x) // @pointsto new@newbool1:10 | new@newbool2:10
27 func final2b(x *bool) {
28 print(x) // @pointsto new@newbool1:10 | new@newbool2:10
31 func runtimeSetFinalizer2() {
32 x := new(bool) // @line newbool1
35 x = new(bool) // @line newbool2
38 runtime.SetFinalizer(x, f)
41 // @calls main.runtimeSetFinalizer2 -> main.final2a
42 // @calls main.runtimeSetFinalizer2 -> main.final2b
46 func (t *T) finalize() {
47 print(t) // @pointsto new@final3:10
50 func runtimeSetFinalizer3() {
51 x := new(T) // @line final3
52 runtime.SetFinalizer(x, (*T).finalize)
55 // @calls main.runtimeSetFinalizer3 -> (*main.T).finalize$thunk
57 // I hope I never live to see this code in the wild.
58 var setFinalizer = runtime.SetFinalizer
61 print(x) // @pointsto new@finalIndirect:10
64 func runtimeSetFinalizerIndirect() {
65 // In an indirect call, the shared contour for SetFinalizer is
66 // used, i.e. the call is not inlined and appears in the call graph.
67 x := new(int) // @line finalIndirect
68 setFinalizer(x, final4)
71 // Exercise the elimination of SetFinalizer
72 // constraints with non-pointer operands.
73 func runtimeSetFinalizerNonpointer() {
74 runtime.SetFinalizer(nil, (*T).finalize) // x is a non-pointer
75 runtime.SetFinalizer((*T).finalize, nil) // f is a non-pointer
78 // @calls main.runtimeSetFinalizerIndirect -> runtime.SetFinalizer
79 // @calls runtime.SetFinalizer -> main.final4
82 runtimeSetFinalizer1()
83 runtimeSetFinalizer2()
84 runtimeSetFinalizer3()
85 runtimeSetFinalizerIndirect()
86 runtimeSetFinalizerNonpointer()
89 var unknown bool // defeat dead-code elimination