github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/finalizer.go (about) 1 package main 2 3 import "runtime" 4 5 func final1a(x *int) int { 6 print(x) // @pointsto new@newint:10 7 return *x 8 } 9 10 func final1b(x *bool) { 11 print(x) // @pointsto 12 } 13 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 18 } 19 20 // @calls command-line-arguments.runtimeSetFinalizer1 -> command-line-arguments.final1a 21 // @calls command-line-arguments.runtimeSetFinalizer1 -> command-line-arguments.final1b 22 23 func final2a(x *bool) { 24 print(x) // @pointsto new@newbool1:10 | new@newbool2:10 25 } 26 27 func final2b(x *bool) { 28 print(x) // @pointsto new@newbool1:10 | new@newbool2:10 29 } 30 31 func runtimeSetFinalizer2() { 32 x := new(bool) // @line newbool1 33 f := final2a 34 if unknown { 35 x = new(bool) // @line newbool2 36 f = final2b 37 } 38 runtime.SetFinalizer(x, f) 39 } 40 41 // @calls command-line-arguments.runtimeSetFinalizer2 -> command-line-arguments.final2a 42 // @calls command-line-arguments.runtimeSetFinalizer2 -> command-line-arguments.final2b 43 44 type T int 45 46 func (t *T) finalize() { 47 print(t) // @pointsto new@final3:10 48 } 49 50 func runtimeSetFinalizer3() { 51 x := new(T) // @line final3 52 runtime.SetFinalizer(x, (*T).finalize) 53 } 54 55 // @calls command-line-arguments.runtimeSetFinalizer3 -> (*command-line-arguments.T).finalize$thunk 56 57 // I hope I never live to see this code in the wild. 58 var setFinalizer = runtime.SetFinalizer 59 60 func final4(x *int) { 61 print(x) // @pointsto new@finalIndirect:10 62 } 63 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) 69 } 70 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 76 } 77 78 // @calls command-line-arguments.runtimeSetFinalizerIndirect -> runtime.SetFinalizer 79 // @calls runtime.SetFinalizer -> command-line-arguments.final4 80 81 func main() { 82 runtimeSetFinalizer1() 83 runtimeSetFinalizer2() 84 runtimeSetFinalizer3() 85 runtimeSetFinalizerIndirect() 86 runtimeSetFinalizerNonpointer() 87 } 88 89 var unknown bool // defeat dead-code elimination