PR testsuite/86649
[official-gcc.git] / gcc / testsuite / go.test / test / deferfin.go
blob80372916d20b303303483f6ea36911b20482c8dc
1 // run
3 // Copyright 2013 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Test that defers do not prevent garbage collection.
9 package main
11 import (
12 "runtime"
13 "sync"
14 "sync/atomic"
15 "time"
18 var sink func()
20 func main() {
21 // Does not work on 32-bits due to partially conservative GC.
22 // Try to enable when we have fully precise GC.
23 if runtime.GOARCH != "amd64" {
24 return
26 // Likewise for gccgo.
27 if runtime.Compiler == "gccgo" {
28 return
30 N := 10
31 count := int32(N)
32 var wg sync.WaitGroup
33 wg.Add(N)
34 for i := 0; i < N; i++ {
35 go func() {
36 defer wg.Done()
37 v := new(string)
38 f := func() {
39 if *v != "" {
40 panic("oops")
43 if *v != "" {
44 // let the compiler think f escapes
45 sink = f
47 runtime.SetFinalizer(v, func(p *string) {
48 atomic.AddInt32(&count, -1)
50 defer f()
51 }()
53 wg.Wait()
54 for i := 0; i < 3; i++ {
55 time.Sleep(10 * time.Millisecond)
56 runtime.GC()
58 if count != 0 {
59 println(count, "out of", N, "finalizer are not called")
60 panic("not all finalizers are called")