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