]> Cypherpunks.ru repositories - gostls13.git/blob - test/live.go
Merge "all: REVERSE MERGE dev.typeparams (4d3cc84) into master"
[gostls13.git] / test / live.go
1 // errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off
2 // +build !ppc64,!ppc64le,!goexperiment.regabiargs
3
4 // ppc64 needs a better tighten pass to make f18 pass
5 // rescheduling checks need to be turned off because there are some live variables across the inserted check call
6 //
7 // For register ABI, liveness info changes slightly. See live_regabi.go.
8
9 // Copyright 2014 The Go Authors. All rights reserved.
10 // Use of this source code is governed by a BSD-style
11 // license that can be found in the LICENSE file.
12
13 // liveness tests with inlining disabled.
14 // see also live2.go.
15
16 package main
17
18 func printnl()
19
20 //go:noescape
21 func printpointer(**int)
22
23 //go:noescape
24 func printintpointer(*int)
25
26 //go:noescape
27 func printstringpointer(*string)
28
29 //go:noescape
30 func printstring(string)
31
32 //go:noescape
33 func printbytepointer(*byte)
34
35 func printint(int)
36
37 func f1() {
38         var x *int       // ERROR "stack object x \*int$"
39         printpointer(&x) // ERROR "live at call to printpointer: x$"
40         printpointer(&x)
41 }
42
43 func f2(b bool) {
44         if b {
45                 printint(0) // nothing live here
46                 return
47         }
48         var x *int       // ERROR "stack object x \*int$"
49         printpointer(&x) // ERROR "live at call to printpointer: x$"
50         printpointer(&x)
51 }
52
53 func f3(b1, b2 bool) {
54         // Here x and y are ambiguously live. In previous go versions they
55         // were marked as live throughout the function to avoid being
56         // poisoned in GODEBUG=gcdead=1 mode; this is now no longer the
57         // case.
58
59         printint(0)
60         if b1 == false {
61                 printint(0)
62                 return
63         }
64
65         if b2 {
66                 var x *int       // ERROR "stack object x \*int$"
67                 printpointer(&x) // ERROR "live at call to printpointer: x$"
68                 printpointer(&x)
69         } else {
70                 var y *int       // ERROR "stack object y \*int$"
71                 printpointer(&y) // ERROR "live at call to printpointer: y$"
72                 printpointer(&y)
73         }
74         printint(0) // nothing is live here
75 }
76
77 // The old algorithm treated x as live on all code that
78 // could flow to a return statement, so it included the
79 // function entry and code above the declaration of x
80 // but would not include an indirect use of x in an infinite loop.
81 // Check that these cases are handled correctly.
82
83 func f4(b1, b2 bool) { // x not live here
84         if b2 {
85                 printint(0) // x not live here
86                 return
87         }
88         var z **int
89         x := new(int) // ERROR "stack object x \*int$"
90         *x = 42
91         z = &x
92         printint(**z) // ERROR "live at call to printint: x$"
93         if b2 {
94                 printint(1) // x not live here
95                 return
96         }
97         for {
98                 printint(**z) // ERROR "live at call to printint: x$"
99         }
100 }
101
102 func f5(b1 bool) {
103         var z **int
104         if b1 {
105                 x := new(int) // ERROR "stack object x \*int$"
106                 *x = 42
107                 z = &x
108         } else {
109                 y := new(int) // ERROR "stack object y \*int$"
110                 *y = 54
111                 z = &y
112         }
113         printint(**z) // nothing live here
114 }
115
116 // confusion about the _ result used to cause spurious "live at entry to f6: _".
117
118 func f6() (_, y string) {
119         y = "hello"
120         return
121 }
122
123 // confusion about addressed results used to cause "live at entry to f7: x".
124
125 func f7() (x string) { // ERROR "stack object x string"
126         _ = &x
127         x = "hello"
128         return
129 }
130
131 // ignoring block returns used to cause "live at entry to f8: x, y".
132
133 func f8() (x, y string) {
134         return g8()
135 }
136
137 func g8() (string, string)
138
139 // ignoring block assignments used to cause "live at entry to f9: x"
140 // issue 7205
141
142 var i9 interface{}
143
144 func f9() bool {
145         g8()
146         x := i9
147         y := interface{}(g18()) // ERROR "live at call to convT: x.data$" "live at call to g18: x.data$" "stack object .autotmp_[0-9]+ \[2\]string$"
148         i9 = y                  // make y escape so the line above has to call convT
149         return x != y
150 }
151
152 // liveness formerly confused by UNDEF followed by RET,
153 // leading to "live at entry to f10: ~r1" (unnamed result).
154
155 func f10() string {
156         panic(1)
157 }
158
159 // liveness formerly confused by select, thinking runtime.selectgo
160 // can return to next instruction; it always jumps elsewhere.
161 // note that you have to use at least two cases in the select
162 // to get a true select; smaller selects compile to optimized helper functions.
163
164 var c chan *int
165 var b bool
166
167 // this used to have a spurious "live at entry to f11a: ~r0"
168 func f11a() *int {
169         select { // ERROR "stack object .autotmp_[0-9]+ \[2\]struct"
170         case <-c:
171                 return nil
172         case <-c:
173                 return nil
174         }
175 }
176
177 func f11b() *int {
178         p := new(int)
179         if b {
180                 // At this point p is dead: the code here cannot
181                 // get to the bottom of the function.
182                 // This used to have a spurious "live at call to printint: p".
183                 printint(1) // nothing live here!
184                 select {    // ERROR "stack object .autotmp_[0-9]+ \[2\]struct"
185                 case <-c:
186                         return nil
187                 case <-c:
188                         return nil
189                 }
190         }
191         println(*p)
192         return nil
193 }
194
195 var sink *int
196
197 func f11c() *int {
198         p := new(int)
199         sink = p // prevent stack allocation, otherwise p is rematerializeable
200         if b {
201                 // Unlike previous, the cases in this select fall through,
202                 // so we can get to the println, so p is not dead.
203                 printint(1) // ERROR "live at call to printint: p$"
204                 select {    // ERROR "live at call to selectgo: p$" "stack object .autotmp_[0-9]+ \[2\]struct"
205                 case <-c:
206                 case <-c:
207                 }
208         }
209         println(*p)
210         return nil
211 }
212
213 // similarly, select{} does not fall through.
214 // this used to have a spurious "live at entry to f12: ~r0".
215
216 func f12() *int {
217         if b {
218                 select {}
219         } else {
220                 return nil
221         }
222 }
223
224 // incorrectly placed VARDEF annotations can cause missing liveness annotations.
225 // this used to be missing the fact that s is live during the call to g13 (because it is
226 // needed for the call to h13).
227
228 func f13() {
229         s := g14()
230         s = h13(s, g13(s)) // ERROR "live at call to g13: s.ptr$"
231 }
232
233 func g13(string) string
234 func h13(string, string) string
235
236 // more incorrectly placed VARDEF.
237
238 func f14() {
239         x := g14() // ERROR "stack object x string$"
240         printstringpointer(&x)
241 }
242
243 func g14() string
244
245 // Checking that various temporaries do not persist or cause
246 // ambiguously live values that must be zeroed.
247 // The exact temporary names are inconsequential but we are
248 // trying to check that there is only one at any given site,
249 // and also that none show up in "ambiguously live" messages.
250
251 var m map[string]int
252 var mi map[interface{}]int
253
254 // str and iface are used to ensure that a temp is required for runtime calls below.
255 func str() string
256 func iface() interface{}
257
258 func f16() {
259         if b {
260                 delete(mi, iface()) // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
261         }
262         delete(mi, iface())
263         delete(mi, iface())
264 }
265
266 var m2s map[string]*byte
267 var m2 map[[2]string]*byte
268 var x2 [2]string
269 var bp *byte
270
271 func f17a(p *byte) { // ERROR "live at entry to f17a: p$"
272         if b {
273                 m2[x2] = p // ERROR "live at call to mapassign: p$"
274         }
275         m2[x2] = p // ERROR "live at call to mapassign: p$"
276         m2[x2] = p // ERROR "live at call to mapassign: p$"
277 }
278
279 func f17b(p *byte) { // ERROR "live at entry to f17b: p$"
280         // key temporary
281         if b {
282                 m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
283         }
284         m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
285         m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
286 }
287
288 func f17c() {
289         // key and value temporaries
290         if b {
291                 m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
292         }
293         m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
294         m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
295 }
296
297 func f17d() *byte
298
299 func g18() [2]string
300
301 func f18() {
302         // key temporary for mapaccess.
303         // temporary introduced by orderexpr.
304         var z *byte
305         if b {
306                 z = m2[g18()] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
307         }
308         z = m2[g18()]
309         z = m2[g18()]
310         printbytepointer(z)
311 }
312
313 var ch chan *byte
314
315 // byteptr is used to ensure that a temp is required for runtime calls below.
316 func byteptr() *byte
317
318 func f19() {
319         // dest temporary for channel receive.
320         var z *byte
321
322         if b {
323                 z = <-ch // ERROR "stack object .autotmp_[0-9]+ \*byte$"
324         }
325         z = <-ch
326         z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
327         printbytepointer(z)
328 }
329
330 func f20() {
331         // src temporary for channel send
332         if b {
333                 ch <- byteptr() // ERROR "stack object .autotmp_[0-9]+ \*byte$"
334         }
335         ch <- byteptr()
336         ch <- byteptr()
337 }
338
339 func f21() {
340         // key temporary for mapaccess using array literal key.
341         var z *byte
342         if b {
343                 z = m2[[2]string{"x", "y"}] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
344         }
345         z = m2[[2]string{"x", "y"}]
346         z = m2[[2]string{"x", "y"}]
347         printbytepointer(z)
348 }
349
350 func f23() {
351         // key temporary for two-result map access using array literal key.
352         var z *byte
353         var ok bool
354         if b {
355                 z, ok = m2[[2]string{"x", "y"}] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
356         }
357         z, ok = m2[[2]string{"x", "y"}]
358         z, ok = m2[[2]string{"x", "y"}]
359         printbytepointer(z)
360         print(ok)
361 }
362
363 func f24() {
364         // key temporary for map access using array literal key.
365         // value temporary too.
366         if b {
367                 m2[[2]string{"x", "y"}] = nil // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
368         }
369         m2[[2]string{"x", "y"}] = nil
370         m2[[2]string{"x", "y"}] = nil
371 }
372
373 // Non-open-coded defers should not cause autotmps.  (Open-coded defers do create extra autotmps).
374 func f25(b bool) {
375         for i := 0; i < 2; i++ {
376                 // Put in loop to make sure defer is not open-coded
377                 defer g25()
378         }
379         if b {
380                 return
381         }
382         var x string
383         x = g14()
384         printstring(x)
385         return
386 }
387
388 func g25()
389
390 // non-escaping ... slices passed to function call should die on return,
391 // so that the temporaries do not stack and do not cause ambiguously
392 // live variables.
393
394 func f26(b bool) {
395         if b {
396                 print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "stack object .autotmp_[0-9]+ \[3\]interface \{\}$"
397         }
398         print26((*int)(nil), (*int)(nil), (*int)(nil))
399         print26((*int)(nil), (*int)(nil), (*int)(nil))
400         printnl()
401 }
402
403 //go:noescape
404 func print26(...interface{})
405
406 // non-escaping closures passed to function call should die on return
407
408 func f27(b bool) {
409         x := 0
410         if b {
411                 call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
412         }
413         call27(func() { x++ })
414         call27(func() { x++ })
415         printnl()
416 }
417
418 // but defer does escape to later execution in the function
419
420 func f27defer(b bool) {
421         x := 0
422         if b {
423                 defer call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
424         }
425         defer call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
426         printnl()                    // ERROR "live at call to printnl: .autotmp_[0-9]+ .autotmp_[0-9]+"
427         return                       // ERROR "live at indirect call: .autotmp_[0-9]+"
428 }
429
430 // and newproc (go) escapes to the heap
431
432 func f27go(b bool) {
433         x := 0
434         if b {
435                 go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" "live at call to newobject: &x .autotmp_[0-9]+$" "live at call to newproc: &x$" // allocate two closures, the func literal, and the wrapper for go
436         }
437         go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" "live at call to newobject: .autotmp_[0-9]+$" // allocate two closures, the func literal, and the wrapper for go
438         printnl()
439 }
440
441 //go:noescape
442 func call27(func())
443
444 // concatstring slice should die on return
445
446 var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
447
448 func f28(b bool) {
449         if b {
450                 printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "stack object .autotmp_[0-9]+ \[10\]string$"
451         }
452         printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10)
453         printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10)
454 }
455
456 // map iterator should die on end of range loop
457
458 func f29(b bool) {
459         if b {
460                 for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ map.iter\[string\]int$"
461                         printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
462                 }
463         }
464         for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
465                 printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
466         }
467         for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
468                 printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
469         }
470 }
471
472 // copy of array of pointers should die at end of range loop
473 var pstructarr [10]pstruct
474
475 // Struct size chosen to make pointer to element in pstructarr
476 // not computable by strength reduction.
477 type pstruct struct {
478         intp *int
479         _    [8]byte
480 }
481
482 func f30(b bool) {
483         // live temp during printintpointer(p):
484         // the internal iterator pointer if a pointer to pstruct in pstructarr
485         // can not be easily computed by strength reduction.
486         if b {
487                 for _, p := range pstructarr { // ERROR "stack object .autotmp_[0-9]+ \[10\]pstruct$"
488                         printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
489                 }
490         }
491         for _, p := range pstructarr {
492                 printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
493         }
494         for _, p := range pstructarr {
495                 printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
496         }
497 }
498
499 // conversion to interface should not leave temporary behind
500
501 func f31(b1, b2, b3 bool) {
502         if b1 {
503                 g31(g18()) // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
504         }
505         if b2 {
506                 h31(g18()) // ERROR "live at call to convT: .autotmp_[0-9]+$" "live at call to newobject: .autotmp_[0-9]+$"
507         }
508         if b3 {
509                 panic(g18())
510         }
511         print(b3)
512 }
513
514 func g31(interface{})
515 func h31(...interface{})
516
517 // non-escaping partial functions passed to function call should die on return
518
519 type T32 int
520
521 func (t *T32) Inc() { // ERROR "live at entry to \(\*T32\).Inc: t$"
522         *t++
523 }
524
525 var t32 T32
526
527 func f32(b bool) {
528         if b {
529                 call32(t32.Inc) // ERROR "stack object .autotmp_[0-9]+ struct \{"
530         }
531         call32(t32.Inc)
532         call32(t32.Inc)
533 }
534
535 //go:noescape
536 func call32(func())
537
538 // temporaries introduced during if conditions and && || expressions
539 // should die once the condition has been acted upon.
540
541 var m33 map[interface{}]int
542
543 func f33() {
544         if m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
545                 printnl()
546                 return
547         } else {
548                 printnl()
549         }
550         printnl()
551 }
552
553 func f34() {
554         if m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
555                 printnl()
556                 return
557         }
558         printnl()
559 }
560
561 func f35() {
562         if m33[byteptr()] == 0 && // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
563                 m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
564                 printnl()
565                 return
566         }
567         printnl()
568 }
569
570 func f36() {
571         if m33[byteptr()] == 0 || // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
572                 m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
573                 printnl()
574                 return
575         }
576         printnl()
577 }
578
579 func f37() {
580         if (m33[byteptr()] == 0 || // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
581                 m33[byteptr()] == 0) && // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
582                 m33[byteptr()] == 0 {
583                 printnl()
584                 return
585         }
586         printnl()
587 }
588
589 // select temps should disappear in the case bodies
590
591 var c38 chan string
592
593 func fc38() chan string
594 func fi38(int) *string
595 func fb38() *bool
596
597 func f38(b bool) {
598         // we don't care what temps are printed on the lines with output.
599         // we care that the println lines have no live variables
600         // and therefore no output.
601         if b {
602                 select { // ERROR "live at call to selectgo:( .autotmp_[0-9]+)+$" "stack object .autotmp_[0-9]+ \[4\]struct \{"
603                 case <-fc38():
604                         printnl()
605                 case fc38() <- *fi38(1): // ERROR "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$" "stack object .autotmp_[0-9]+ string$"
606                         printnl()
607                 case *fi38(2) = <-fc38(): // ERROR "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$" "stack object .autotmp_[0-9]+ string$"
608                         printnl()
609                 case *fi38(3), *fb38() = <-fc38(): // ERROR "stack object .autotmp_[0-9]+ string$" "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$"
610                         printnl()
611                 }
612                 printnl()
613         }
614         printnl()
615 }
616
617 // issue 8097: mishandling of x = x during return.
618
619 func f39() (x []int) {
620         x = []int{1}
621         printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
622         return x
623 }
624
625 func f39a() (x []int) {
626         x = []int{1}
627         printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
628         return
629 }
630
631 func f39b() (x [10]*int) {
632         x = [10]*int{}
633         x[0] = new(int) // ERROR "live at call to newobject: x$"
634         printnl()       // ERROR "live at call to printnl: x$"
635         return x
636 }
637
638 func f39c() (x [10]*int) {
639         x = [10]*int{}
640         x[0] = new(int) // ERROR "live at call to newobject: x$"
641         printnl()       // ERROR "live at call to printnl: x$"
642         return
643 }
644
645 // issue 8142: lost 'addrtaken' bit on inlined variables.
646 // no inlining in this test, so just checking that non-inlined works.
647
648 type T40 struct {
649         m map[int]int
650 }
651
652 //go:noescape
653 func useT40(*T40)
654
655 func newT40() *T40 {
656         ret := T40{}
657         ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
658         return &ret
659 }
660
661 func bad40() {
662         t := newT40()
663         _ = t
664         printnl()
665 }
666
667 func good40() {
668         ret := T40{}              // ERROR "stack object ret T40$"
669         ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
670         t := &ret
671         printnl() // ERROR "live at call to printnl: ret$"
672         // Note: ret is live at the printnl because the compiler moves &ret
673         // from before the printnl to after.
674         useT40(t)
675 }
676
677 func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
678         ddd2(x, y) // ERROR "stack object .autotmp_[0-9]+ \[2\]\*int$"
679         printnl()
680         // Note: no .?autotmp live at printnl.  See issue 16996.
681 }
682 func ddd2(a ...*int) { // ERROR "live at entry to ddd2: a$"
683         sink = a[0]
684 }
685
686 // issue 16016: autogenerated wrapper should have arguments live
687 type T struct{}
688
689 func (*T) Foo(ptr *int) {}
690
691 type R struct{ *T }
692
693 // issue 18860: output arguments must be live all the time if there is a defer.
694 // In particular, at printint r must be live.
695 func f41(p, q *int) (r *int) { // ERROR "live at entry to f41: p q$"
696         r = p
697         defer func() {
698                 recover()
699         }()
700         printint(0) // ERROR "live at call to printint: q r .autotmp_[0-9]+$"
701         r = q
702         return // ERROR "live at call to f41.func1: r .autotmp_[0-9]+$"
703 }
704
705 func f42() {
706         var p, q, r int
707         f43([]*int{&p, &q, &r}) // ERROR "stack object .autotmp_[0-9]+ \[3\]\*int$"
708         f43([]*int{&p, &r, &q})
709         f43([]*int{&q, &p, &r})
710 }
711
712 //go:noescape
713 func f43(a []*int)
714
715 // Assigning to a sub-element that makes up an entire local variable
716 // should clobber that variable.
717 func f44(f func() [2]*int) interface{} { // ERROR "live at entry to f44: f"
718         type T struct {
719                 s [1][2]*int
720         }
721         ret := T{}
722         ret.s[0] = f()
723         return ret // ERROR "stack object .autotmp_[0-9]+ T"
724 }