[go: up one dir, main page]

blob: 46e5e3e757cd60578c22c46e3ae100ce302b981a [file] [log] [blame]
David Chase7f1ff652016-11-10 16:03:47 -05001// errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off
Dmitri Shuralyovb2fd76a2023-10-17 15:07:58 -04002
Matthew Dempsky8003efe2022-08-09 01:32:22 -07003//go:build !ppc64 && !ppc64le && !goexperiment.regabiargs
Joel Sing212c0bf2020-01-29 05:30:19 +11004
Keith Randallc199c762016-09-16 12:11:33 -07005// ppc64 needs a better tighten pass to make f18 pass
David Chase7f1ff652016-11-10 16:03:47 -05006// rescheduling checks need to be turned off because there are some live variables across the inserted check call
Cherry Zhanga9c244a2021-04-17 00:46:53 -04007//
8// For register ABI, liveness info changes slightly. See live_regabi.go.
Keith Randall4a7aba72016-03-28 11:25:17 -07009
Emmanuel Odeke53fd5222016-04-10 14:32:26 -070010// Copyright 2014 The Go Authors. All rights reserved.
Keith Randall4a7aba72016-03-28 11:25:17 -070011// Use of this source code is governed by a BSD-style
12// license that can be found in the LICENSE file.
13
14// liveness tests with inlining disabled.
15// see also live2.go.
16
17package main
18
19func printnl()
20
21//go:noescape
22func printpointer(**int)
23
24//go:noescape
25func printintpointer(*int)
26
27//go:noescape
28func printstringpointer(*string)
29
30//go:noescape
31func printstring(string)
32
33//go:noescape
34func printbytepointer(*byte)
35
36func printint(int)
37
38func f1() {
Keith Randall9a8372f2018-09-07 14:55:09 -070039 var x *int // ERROR "stack object x \*int$"
Keith Randall4a7aba72016-03-28 11:25:17 -070040 printpointer(&x) // ERROR "live at call to printpointer: x$"
Keith Randall9a8372f2018-09-07 14:55:09 -070041 printpointer(&x)
Keith Randall4a7aba72016-03-28 11:25:17 -070042}
43
44func f2(b bool) {
45 if b {
46 printint(0) // nothing live here
47 return
48 }
Keith Randall9a8372f2018-09-07 14:55:09 -070049 var x *int // ERROR "stack object x \*int$"
Keith Randall4a7aba72016-03-28 11:25:17 -070050 printpointer(&x) // ERROR "live at call to printpointer: x$"
Keith Randall9a8372f2018-09-07 14:55:09 -070051 printpointer(&x)
Keith Randall4a7aba72016-03-28 11:25:17 -070052}
53
54func f3(b1, b2 bool) {
Than McIntosh6c5e3772016-07-14 13:23:11 -040055 // Here x and y are ambiguously live. In previous go versions they
56 // were marked as live throughout the function to avoid being
57 // poisoned in GODEBUG=gcdead=1 mode; this is now no longer the
58 // case.
Keith Randall4a7aba72016-03-28 11:25:17 -070059
Than McIntosh6c5e3772016-07-14 13:23:11 -040060 printint(0)
Keith Randall4a7aba72016-03-28 11:25:17 -070061 if b1 == false {
Than McIntosh6c5e3772016-07-14 13:23:11 -040062 printint(0)
Keith Randall4a7aba72016-03-28 11:25:17 -070063 return
64 }
65
66 if b2 {
Keith Randall9a8372f2018-09-07 14:55:09 -070067 var x *int // ERROR "stack object x \*int$"
Than McIntosh6c5e3772016-07-14 13:23:11 -040068 printpointer(&x) // ERROR "live at call to printpointer: x$"
Keith Randall9a8372f2018-09-07 14:55:09 -070069 printpointer(&x)
Keith Randall4a7aba72016-03-28 11:25:17 -070070 } else {
Keith Randall9a8372f2018-09-07 14:55:09 -070071 var y *int // ERROR "stack object y \*int$"
Than McIntosh6c5e3772016-07-14 13:23:11 -040072 printpointer(&y) // ERROR "live at call to printpointer: y$"
Keith Randall9a8372f2018-09-07 14:55:09 -070073 printpointer(&y)
Keith Randall4a7aba72016-03-28 11:25:17 -070074 }
Keith Randall9a8372f2018-09-07 14:55:09 -070075 printint(0) // nothing is live here
Keith Randall4a7aba72016-03-28 11:25:17 -070076}
77
78// The old algorithm treated x as live on all code that
79// could flow to a return statement, so it included the
80// function entry and code above the declaration of x
81// but would not include an indirect use of x in an infinite loop.
82// Check that these cases are handled correctly.
83
84func f4(b1, b2 bool) { // x not live here
85 if b2 {
86 printint(0) // x not live here
87 return
88 }
89 var z **int
Keith Randall9a8372f2018-09-07 14:55:09 -070090 x := new(int) // ERROR "stack object x \*int$"
Keith Randall4a7aba72016-03-28 11:25:17 -070091 *x = 42
92 z = &x
93 printint(**z) // ERROR "live at call to printint: x$"
94 if b2 {
95 printint(1) // x not live here
96 return
97 }
98 for {
99 printint(**z) // ERROR "live at call to printint: x$"
100 }
101}
102
103func f5(b1 bool) {
104 var z **int
105 if b1 {
Keith Randall9a8372f2018-09-07 14:55:09 -0700106 x := new(int) // ERROR "stack object x \*int$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700107 *x = 42
108 z = &x
109 } else {
Keith Randall9a8372f2018-09-07 14:55:09 -0700110 y := new(int) // ERROR "stack object y \*int$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700111 *y = 54
112 z = &y
113 }
Keith Randall9a8372f2018-09-07 14:55:09 -0700114 printint(**z) // nothing live here
Keith Randall4a7aba72016-03-28 11:25:17 -0700115}
116
117// confusion about the _ result used to cause spurious "live at entry to f6: _".
118
119func f6() (_, y string) {
120 y = "hello"
121 return
122}
123
124// confusion about addressed results used to cause "live at entry to f7: x".
125
Keith Randall9a8372f2018-09-07 14:55:09 -0700126func f7() (x string) { // ERROR "stack object x string"
Keith Randall4a7aba72016-03-28 11:25:17 -0700127 _ = &x
128 x = "hello"
129 return
130}
131
132// ignoring block returns used to cause "live at entry to f8: x, y".
133
134func f8() (x, y string) {
135 return g8()
136}
137
138func g8() (string, string)
139
140// ignoring block assignments used to cause "live at entry to f9: x"
141// issue 7205
142
143var i9 interface{}
144
145func f9() bool {
146 g8()
147 x := i9
Keith Randall57668b82021-08-04 22:18:23 -0700148 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$"
149 i9 = y // make y escape so the line above has to call convT
Keith Randall6129f372016-09-17 15:04:36 -0700150 return x != y
Keith Randall4a7aba72016-03-28 11:25:17 -0700151}
152
153// liveness formerly confused by UNDEF followed by RET,
154// leading to "live at entry to f10: ~r1" (unnamed result).
155
156func f10() string {
157 panic(1)
158}
159
160// liveness formerly confused by select, thinking runtime.selectgo
161// can return to next instruction; it always jumps elsewhere.
162// note that you have to use at least two cases in the select
163// to get a true select; smaller selects compile to optimized helper functions.
164
165var c chan *int
166var b bool
167
168// this used to have a spurious "live at entry to f11a: ~r0"
169func f11a() *int {
Matthew Dempskyfecf5172023-08-21 14:08:46 -0700170 select { // ERROR "stack object .autotmp_[0-9]+ \[2\]runtime.scase$"
Matthew Dempsky004260a2017-03-07 14:26:27 -0800171 case <-c:
Keith Randall4a7aba72016-03-28 11:25:17 -0700172 return nil
Matthew Dempsky004260a2017-03-07 14:26:27 -0800173 case <-c:
Keith Randall4a7aba72016-03-28 11:25:17 -0700174 return nil
175 }
176}
177
178func f11b() *int {
179 p := new(int)
180 if b {
181 // At this point p is dead: the code here cannot
182 // get to the bottom of the function.
183 // This used to have a spurious "live at call to printint: p".
184 printint(1) // nothing live here!
Matthew Dempskyfecf5172023-08-21 14:08:46 -0700185 select { // ERROR "stack object .autotmp_[0-9]+ \[2\]runtime.scase$"
Matthew Dempsky004260a2017-03-07 14:26:27 -0800186 case <-c:
Keith Randall4a7aba72016-03-28 11:25:17 -0700187 return nil
Matthew Dempsky004260a2017-03-07 14:26:27 -0800188 case <-c:
Keith Randall4a7aba72016-03-28 11:25:17 -0700189 return nil
190 }
191 }
192 println(*p)
193 return nil
194}
195
196var sink *int
197
198func f11c() *int {
199 p := new(int)
200 sink = p // prevent stack allocation, otherwise p is rematerializeable
201 if b {
202 // Unlike previous, the cases in this select fall through,
203 // so we can get to the println, so p is not dead.
204 printint(1) // ERROR "live at call to printint: p$"
Matthew Dempskyfecf5172023-08-21 14:08:46 -0700205 select { // ERROR "live at call to selectgo: p$" "stack object .autotmp_[0-9]+ \[2\]runtime.scase$"
Matthew Dempsky004260a2017-03-07 14:26:27 -0800206 case <-c:
207 case <-c:
Keith Randall4a7aba72016-03-28 11:25:17 -0700208 }
209 }
210 println(*p)
211 return nil
212}
213
214// similarly, select{} does not fall through.
215// this used to have a spurious "live at entry to f12: ~r0".
216
217func f12() *int {
218 if b {
219 select {}
220 } else {
221 return nil
222 }
223}
224
225// incorrectly placed VARDEF annotations can cause missing liveness annotations.
226// this used to be missing the fact that s is live during the call to g13 (because it is
227// needed for the call to h13).
228
229func f13() {
230 s := g14()
231 s = h13(s, g13(s)) // ERROR "live at call to g13: s.ptr$"
232}
233
234func g13(string) string
235func h13(string, string) string
236
237// more incorrectly placed VARDEF.
238
239func f14() {
Keith Randall9a8372f2018-09-07 14:55:09 -0700240 x := g14() // ERROR "stack object x string$"
241 printstringpointer(&x)
Keith Randall4a7aba72016-03-28 11:25:17 -0700242}
243
244func g14() string
245
Keith Randall4a7aba72016-03-28 11:25:17 -0700246// Checking that various temporaries do not persist or cause
247// ambiguously live values that must be zeroed.
248// The exact temporary names are inconsequential but we are
249// trying to check that there is only one at any given site,
250// and also that none show up in "ambiguously live" messages.
251
252var m map[string]int
Hugues Bruant5d6b7fc2017-03-14 11:11:28 -0700253var mi map[interface{}]int
Keith Randall4a7aba72016-03-28 11:25:17 -0700254
Hugues Bruant5d6b7fc2017-03-14 11:11:28 -0700255// str and iface are used to ensure that a temp is required for runtime calls below.
Josh Bleecher Snyderc682d322017-01-21 13:41:06 -0800256func str() string
Hugues Bruant5d6b7fc2017-03-14 11:11:28 -0700257func iface() interface{}
Josh Bleecher Snyderc682d322017-01-21 13:41:06 -0800258
Keith Randall4a7aba72016-03-28 11:25:17 -0700259func f16() {
260 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700261 delete(mi, iface()) // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700262 }
Keith Randall389e9422018-10-05 08:54:50 -0700263 delete(mi, iface())
264 delete(mi, iface())
Keith Randall4a7aba72016-03-28 11:25:17 -0700265}
266
267var m2s map[string]*byte
268var m2 map[[2]string]*byte
269var x2 [2]string
270var bp *byte
271
Keith Randall442de982016-10-11 08:36:38 -0700272func f17a(p *byte) { // ERROR "live at entry to f17a: p$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700273 if b {
Keith Randall442de982016-10-11 08:36:38 -0700274 m2[x2] = p // ERROR "live at call to mapassign: p$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700275 }
Keith Randall442de982016-10-11 08:36:38 -0700276 m2[x2] = p // ERROR "live at call to mapassign: p$"
277 m2[x2] = p // ERROR "live at call to mapassign: p$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700278}
279
Michael Prattf782e162024-09-19 16:06:40 -0400280func f17b(p *byte) { // ERROR "live at entry to f17b: p$"
281 // key temporary
282 if b {
283 m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
284 }
285 m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
286 m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
287}
288
289func f17c() {
290 // key and value temporaries
291 if b {
292 m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
293 }
294 m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
295 m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
296}
297
298func f17d() *byte
299
Keith Randall4a7aba72016-03-28 11:25:17 -0700300func g18() [2]string
301
302func f18() {
303 // key temporary for mapaccess.
304 // temporary introduced by orderexpr.
305 var z *byte
306 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700307 z = m2[g18()] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700308 }
Keith Randall389e9422018-10-05 08:54:50 -0700309 z = m2[g18()]
310 z = m2[g18()]
Keith Randall4a7aba72016-03-28 11:25:17 -0700311 printbytepointer(z)
312}
313
314var ch chan *byte
315
Josh Bleecher Snyderc682d322017-01-21 13:41:06 -0800316// byteptr is used to ensure that a temp is required for runtime calls below.
317func byteptr() *byte
318
Keith Randall4a7aba72016-03-28 11:25:17 -0700319func f19() {
320 // dest temporary for channel receive.
321 var z *byte
322
323 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700324 z = <-ch // ERROR "stack object .autotmp_[0-9]+ \*byte$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700325 }
Keith Randall389e9422018-10-05 08:54:50 -0700326 z = <-ch
327 z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700328 printbytepointer(z)
329}
330
331func f20() {
332 // src temporary for channel send
333 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700334 ch <- byteptr() // ERROR "stack object .autotmp_[0-9]+ \*byte$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700335 }
Keith Randall389e9422018-10-05 08:54:50 -0700336 ch <- byteptr()
337 ch <- byteptr()
Keith Randall4a7aba72016-03-28 11:25:17 -0700338}
339
thepuddsf4de2ec2025-02-13 23:49:50 -0500340func f21(x, y string) { // ERROR "live at entry to f21: x y"
Keith Randall4a7aba72016-03-28 11:25:17 -0700341 // key temporary for mapaccess using array literal key.
342 var z *byte
343 if b {
thepuddsf4de2ec2025-02-13 23:49:50 -0500344 z = m2[[2]string{x, y}] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700345 }
Keith Randall389e9422018-10-05 08:54:50 -0700346 z = m2[[2]string{"x", "y"}]
347 z = m2[[2]string{"x", "y"}]
Keith Randall4a7aba72016-03-28 11:25:17 -0700348 printbytepointer(z)
349}
350
thepuddsf4de2ec2025-02-13 23:49:50 -0500351func f21b() {
352 // key temporary for mapaccess using array literal key.
353 var z *byte
354 if b {
355 z = m2[[2]string{"x", "y"}]
356 }
357 z = m2[[2]string{"x", "y"}]
358 z = m2[[2]string{"x", "y"}]
359 printbytepointer(z)
360}
361
362func f23(x, y string) { // ERROR "live at entry to f23: x y"
Keith Randall4a7aba72016-03-28 11:25:17 -0700363 // key temporary for two-result map access using array literal key.
364 var z *byte
365 var ok bool
366 if b {
thepuddsf4de2ec2025-02-13 23:49:50 -0500367 z, ok = m2[[2]string{x, y}] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700368 }
Keith Randall389e9422018-10-05 08:54:50 -0700369 z, ok = m2[[2]string{"x", "y"}]
370 z, ok = m2[[2]string{"x", "y"}]
Keith Randall4a7aba72016-03-28 11:25:17 -0700371 printbytepointer(z)
372 print(ok)
373}
374
thepuddsf4de2ec2025-02-13 23:49:50 -0500375func f23b() {
376 // key temporary for two-result map access using array literal key.
377 var z *byte
378 var ok bool
379 if b {
380 z, ok = m2[[2]string{"x", "y"}]
381 }
382 z, ok = m2[[2]string{"x", "y"}]
383 z, ok = m2[[2]string{"x", "y"}]
384 printbytepointer(z)
385 print(ok)
386}
387
388func f24(x, y string) { // ERROR "live at entry to f24: x y"
Keith Randall4a7aba72016-03-28 11:25:17 -0700389 // key temporary for map access using array literal key.
390 // value temporary too.
391 if b {
thepuddsf4de2ec2025-02-13 23:49:50 -0500392 m2[[2]string{x, y}] = nil // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
393 }
394 m2[[2]string{"x", "y"}] = nil
395 m2[[2]string{"x", "y"}] = nil
396}
397
398func f24b() {
399 // key temporary for map access using array literal key.
400 // value temporary too.
401 if b {
402 m2[[2]string{"x", "y"}] = nil
Keith Randall4a7aba72016-03-28 11:25:17 -0700403 }
Keith Randall389e9422018-10-05 08:54:50 -0700404 m2[[2]string{"x", "y"}] = nil
405 m2[[2]string{"x", "y"}] = nil
Keith Randall4a7aba72016-03-28 11:25:17 -0700406}
407
Dan Scalesbe64a192019-06-24 12:59:22 -0700408// Non-open-coded defers should not cause autotmps. (Open-coded defers do create extra autotmps).
Keith Randall4a7aba72016-03-28 11:25:17 -0700409func f25(b bool) {
Dan Scalesbe64a192019-06-24 12:59:22 -0700410 for i := 0; i < 2; i++ {
411 // Put in loop to make sure defer is not open-coded
412 defer g25()
413 }
Keith Randall4a7aba72016-03-28 11:25:17 -0700414 if b {
415 return
416 }
417 var x string
Michael Munday744ebfd2017-03-29 14:01:41 -0400418 x = g14()
419 printstring(x)
Dan Scalesbe64a192019-06-24 12:59:22 -0700420 return
Michael Munday744ebfd2017-03-29 14:01:41 -0400421}
Keith Randall4a7aba72016-03-28 11:25:17 -0700422
423func g25()
424
425// non-escaping ... slices passed to function call should die on return,
426// so that the temporaries do not stack and do not cause ambiguously
427// live variables.
428
429func f26(b bool) {
430 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700431 print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "stack object .autotmp_[0-9]+ \[3\]interface \{\}$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700432 }
Keith Randall389e9422018-10-05 08:54:50 -0700433 print26((*int)(nil), (*int)(nil), (*int)(nil))
434 print26((*int)(nil), (*int)(nil), (*int)(nil))
Keith Randall4a7aba72016-03-28 11:25:17 -0700435 printnl()
436}
437
438//go:noescape
439func print26(...interface{})
440
441// non-escaping closures passed to function call should die on return
442
443func f27(b bool) {
444 x := 0
445 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700446 call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
Keith Randall4a7aba72016-03-28 11:25:17 -0700447 }
Keith Randall63e964e12018-10-06 14:31:08 -0700448 call27(func() { x++ })
449 call27(func() { x++ })
Keith Randall4a7aba72016-03-28 11:25:17 -0700450 printnl()
451}
452
453// but defer does escape to later execution in the function
454
455func f27defer(b bool) {
456 x := 0
457 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700458 defer call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
Keith Randall4a7aba72016-03-28 11:25:17 -0700459 }
Keith Randall9a8372f2018-09-07 14:55:09 -0700460 defer call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
Dan Scalesbe64a192019-06-24 12:59:22 -0700461 printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ .autotmp_[0-9]+"
Cherry Mui4cf7f5f2021-06-04 11:09:25 -0400462 return // ERROR "live at indirect call: .autotmp_[0-9]+"
Keith Randall9a8372f2018-09-07 14:55:09 -0700463}
Keith Randall4a7aba72016-03-28 11:25:17 -0700464
465// and newproc (go) escapes to the heap
466
467func f27go(b bool) {
468 x := 0
469 if b {
Cherry Mui4cf7f5f2021-06-04 11:09:25 -0400470 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
Keith Randall4a7aba72016-03-28 11:25:17 -0700471 }
Cherry Mui4cf7f5f2021-06-04 11:09:25 -0400472 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
Keith Randall4a7aba72016-03-28 11:25:17 -0700473 printnl()
474}
475
476//go:noescape
477func call27(func())
478
479// concatstring slice should die on return
480
481var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
482
483func f28(b bool) {
484 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700485 printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "stack object .autotmp_[0-9]+ \[10\]string$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700486 }
Keith Randall389e9422018-10-05 08:54:50 -0700487 printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10)
488 printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10)
Keith Randall4a7aba72016-03-28 11:25:17 -0700489}
490
491// map iterator should die on end of range loop
492
493func f29(b bool) {
494 if b {
Michael Pratt78e6f2a2025-01-24 13:34:26 -0500495 for k := range m { // ERROR "live at call to (mapiterinit|mapIterStart): .autotmp_[0-9]+$" "live at call to (mapiternext|mapIterNext): .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ (runtime.hiter|internal/runtime/maps.Iter)$"
David Chase9c066ba2016-10-28 13:33:57 -0400496 printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700497 }
498 }
Michael Pratt78e6f2a2025-01-24 13:34:26 -0500499 for k := range m { // ERROR "live at call to (mapiterinit|mapIterStart): .autotmp_[0-9]+$" "live at call to (mapiternext|mapIterNext): .autotmp_[0-9]+$"
David Chase9c066ba2016-10-28 13:33:57 -0400500 printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700501 }
Michael Pratt78e6f2a2025-01-24 13:34:26 -0500502 for k := range m { // ERROR "live at call to (mapiterinit|mapIterStart): .autotmp_[0-9]+$" "live at call to (mapiternext|mapIterNext): .autotmp_[0-9]+$"
David Chase9c066ba2016-10-28 13:33:57 -0400503 printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700504 }
505}
506
507// copy of array of pointers should die at end of range loop
Martin Möhrmann743117a2016-12-18 20:13:58 +0100508var pstructarr [10]pstruct
Keith Randall4a7aba72016-03-28 11:25:17 -0700509
Kazuhiro Seraad644d22018-08-23 05:06:47 +0000510// Struct size chosen to make pointer to element in pstructarr
Martin Möhrmann743117a2016-12-18 20:13:58 +0100511// not computable by strength reduction.
512type pstruct struct {
513 intp *int
514 _ [8]byte
515}
Keith Randall4a7aba72016-03-28 11:25:17 -0700516
517func f30(b bool) {
Keith Randall9a8372f2018-09-07 14:55:09 -0700518 // live temp during printintpointer(p):
Martin Möhrmann743117a2016-12-18 20:13:58 +0100519 // the internal iterator pointer if a pointer to pstruct in pstructarr
520 // can not be easily computed by strength reduction.
Keith Randall4a7aba72016-03-28 11:25:17 -0700521 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700522 for _, p := range pstructarr { // ERROR "stack object .autotmp_[0-9]+ \[10\]pstruct$"
523 printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700524 }
525 }
Keith Randall389e9422018-10-05 08:54:50 -0700526 for _, p := range pstructarr {
Keith Randall9a8372f2018-09-07 14:55:09 -0700527 printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700528 }
Keith Randall389e9422018-10-05 08:54:50 -0700529 for _, p := range pstructarr {
Keith Randall9a8372f2018-09-07 14:55:09 -0700530 printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700531 }
532}
533
534// conversion to interface should not leave temporary behind
535
536func f31(b1, b2, b3 bool) {
537 if b1 {
Keith Randall0e9f8a22018-09-14 10:09:08 -0700538 g31(g18()) // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700539 }
540 if b2 {
Keith Randall57668b82021-08-04 22:18:23 -0700541 h31(g18()) // ERROR "live at call to convT: .autotmp_[0-9]+$" "live at call to newobject: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700542 }
543 if b3 {
Keith Randall389e9422018-10-05 08:54:50 -0700544 panic(g18())
Keith Randall4a7aba72016-03-28 11:25:17 -0700545 }
546 print(b3)
547}
548
549func g31(interface{})
550func h31(...interface{})
551
552// non-escaping partial functions passed to function call should die on return
553
554type T32 int
555
556func (t *T32) Inc() { // ERROR "live at entry to \(\*T32\).Inc: t$"
557 *t++
558}
559
560var t32 T32
561
562func f32(b bool) {
563 if b {
Keith Randall9a8372f2018-09-07 14:55:09 -0700564 call32(t32.Inc) // ERROR "stack object .autotmp_[0-9]+ struct \{"
Keith Randall4a7aba72016-03-28 11:25:17 -0700565 }
Keith Randall63e964e12018-10-06 14:31:08 -0700566 call32(t32.Inc)
567 call32(t32.Inc)
Keith Randall4a7aba72016-03-28 11:25:17 -0700568}
569
570//go:noescape
571func call32(func())
572
573// temporaries introduced during if conditions and && || expressions
574// should die once the condition has been acted upon.
575
576var m33 map[interface{}]int
577
578func f33() {
Keith Randall9a8372f2018-09-07 14:55:09 -0700579 if m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700580 printnl()
581 return
582 } else {
583 printnl()
584 }
585 printnl()
586}
587
588func f34() {
Keith Randall9a8372f2018-09-07 14:55:09 -0700589 if m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700590 printnl()
591 return
592 }
593 printnl()
594}
595
596func f35() {
Keith Randall9a8372f2018-09-07 14:55:09 -0700597 if m33[byteptr()] == 0 && // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
598 m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
Keith Randall4a7aba72016-03-28 11:25:17 -0700599 printnl()
600 return
601 }
602 printnl()
603}
604
605func f36() {
Keith Randall9a8372f2018-09-07 14:55:09 -0700606 if m33[byteptr()] == 0 || // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
607 m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
Keith Randall4a7aba72016-03-28 11:25:17 -0700608 printnl()
609 return
610 }
611 printnl()
612}
613
614func f37() {
Keith Randall9a8372f2018-09-07 14:55:09 -0700615 if (m33[byteptr()] == 0 || // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
616 m33[byteptr()] == 0) && // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
Keith Randall4a9064e2019-03-05 17:42:48 -0800617 m33[byteptr()] == 0 {
Keith Randall4a7aba72016-03-28 11:25:17 -0700618 printnl()
619 return
620 }
621 printnl()
622}
623
624// select temps should disappear in the case bodies
625
626var c38 chan string
627
628func fc38() chan string
629func fi38(int) *string
630func fb38() *bool
631
632func f38(b bool) {
633 // we don't care what temps are printed on the lines with output.
634 // we care that the println lines have no live variables
635 // and therefore no output.
636 if b {
Matthew Dempskyfecf5172023-08-21 14:08:46 -0700637 select { // ERROR "live at call to selectgo:( .autotmp_[0-9]+)+$" "stack object .autotmp_[0-9]+ \[4\]runtime.scase$"
Matthew Dempsky004260a2017-03-07 14:26:27 -0800638 case <-fc38():
Keith Randall4a7aba72016-03-28 11:25:17 -0700639 printnl()
Keith Randall9a8372f2018-09-07 14:55:09 -0700640 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$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700641 printnl()
Keith Randall9a8372f2018-09-07 14:55:09 -0700642 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$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700643 printnl()
Matthew Dempsky8003efe2022-08-09 01:32:22 -0700644 case *fi38(3), *fb38() = <-fc38(): // ERROR "stack object .autotmp_[0-9]+ string$" "live at call to f[ibc]38:( .autotmp_[0-9]+)+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700645 printnl()
646 }
647 printnl()
648 }
649 printnl()
650}
651
652// issue 8097: mishandling of x = x during return.
653
654func f39() (x []int) {
655 x = []int{1}
David Chase9c066ba2016-10-28 13:33:57 -0400656 printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700657 return x
658}
659
660func f39a() (x []int) {
661 x = []int{1}
David Chase9c066ba2016-10-28 13:33:57 -0400662 printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700663 return
664}
665
Keith Randall309144b2016-04-01 11:05:30 -0700666func f39b() (x [10]*int) {
667 x = [10]*int{}
668 x[0] = new(int) // ERROR "live at call to newobject: x$"
669 printnl() // ERROR "live at call to printnl: x$"
670 return x
671}
Keith Randall4a7aba72016-03-28 11:25:17 -0700672
673func f39c() (x [10]*int) {
674 x = [10]*int{}
675 x[0] = new(int) // ERROR "live at call to newobject: x$"
676 printnl() // ERROR "live at call to printnl: x$"
677 return
678}
679
680// issue 8142: lost 'addrtaken' bit on inlined variables.
681// no inlining in this test, so just checking that non-inlined works.
682
683type T40 struct {
684 m map[int]int
685}
686
Michael Munday744ebfd2017-03-29 14:01:41 -0400687//go:noescape
688func useT40(*T40)
689
Keith Randall4a7aba72016-03-28 11:25:17 -0700690func newT40() *T40 {
691 ret := T40{}
Martin Möhrmannfbfc2032017-09-02 18:46:59 +0200692 ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
Keith Randall4a7aba72016-03-28 11:25:17 -0700693 return &ret
694}
695
Michael Pratt63ba2b92024-10-25 15:08:54 -0400696func good40() {
697 ret := T40{} // ERROR "stack object ret T40$"
698 ret.m = make(map[int]int) // ERROR "live at call to rand(32)?: .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ (runtime.hmap|internal/runtime/maps.Map)$"
699 t := &ret
700 printnl() // ERROR "live at call to printnl: ret$"
701 // Note: ret is live at the printnl because the compiler moves &ret
702 // from before the printnl to after.
703 useT40(t)
704}
705
Keith Randall4a7aba72016-03-28 11:25:17 -0700706func bad40() {
707 t := newT40()
708 _ = t
709 printnl()
710}
711
Keith Randall83c73a82016-09-06 21:08:21 -0700712func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
Keith Randall9a8372f2018-09-07 14:55:09 -0700713 ddd2(x, y) // ERROR "stack object .autotmp_[0-9]+ \[2\]\*int$"
Keith Randallca4089a2016-08-31 15:17:02 -0700714 printnl()
David Chase9c066ba2016-10-28 13:33:57 -0400715 // Note: no .?autotmp live at printnl. See issue 16996.
Keith Randall83c73a82016-09-06 21:08:21 -0700716}
717func ddd2(a ...*int) { // ERROR "live at entry to ddd2: a$"
718 sink = a[0]
719}
Cherry Zhangd586aae2016-09-22 13:50:16 -0400720
721// issue 16016: autogenerated wrapper should have arguments live
722type T struct{}
723
724func (*T) Foo(ptr *int) {}
725
Matthew Dempsky808dca32021-06-24 12:57:20 -0700726type R struct{ *T }
Keith Randall8179b9b2017-01-30 14:55:12 -0800727
728// issue 18860: output arguments must be live all the time if there is a defer.
729// In particular, at printint r must be live.
730func f41(p, q *int) (r *int) { // ERROR "live at entry to f41: p q$"
731 r = p
Dan Scalesbe64a192019-06-24 12:59:22 -0700732 defer func() {
Keith Randall8179b9b2017-01-30 14:55:12 -0800733 recover()
Robert Griesemer3fd31712017-02-09 16:00:23 -0800734 }()
Keith Randall4ff07492023-01-20 13:36:51 -0800735 printint(0) // ERROR "live at call to printint: .autotmp_[0-9]+ q r$"
Keith Randall8179b9b2017-01-30 14:55:12 -0800736 r = q
Keith Randall4ff07492023-01-20 13:36:51 -0800737 return // ERROR "live at call to f41.func1: .autotmp_[0-9]+ r$"
Keith Randall8179b9b2017-01-30 14:55:12 -0800738}
Keith Randall63e964e12018-10-06 14:31:08 -0700739
740func f42() {
741 var p, q, r int
Keith Randall4a9064e2019-03-05 17:42:48 -0800742 f43([]*int{&p, &q, &r}) // ERROR "stack object .autotmp_[0-9]+ \[3\]\*int$"
743 f43([]*int{&p, &r, &q})
744 f43([]*int{&q, &p, &r})
Keith Randall63e964e12018-10-06 14:31:08 -0700745}
Keith Randall4a9064e2019-03-05 17:42:48 -0800746
Keith Randall63e964e12018-10-06 14:31:08 -0700747//go:noescape
748func f43(a []*int)
Cuong Manh Led2f958d2019-09-03 23:24:35 +0700749
750// Assigning to a sub-element that makes up an entire local variable
751// should clobber that variable.
752func f44(f func() [2]*int) interface{} { // ERROR "live at entry to f44: f"
753 type T struct {
754 s [1][2]*int
755 }
Keith Randall908499a2022-07-22 14:58:40 -0700756 ret := T{} // ERROR "stack object ret T"
Cuong Manh Led2f958d2019-09-03 23:24:35 +0700757 ret.s[0] = f()
Keith Randall908499a2022-07-22 14:58:40 -0700758 return ret
Cuong Manh Led2f958d2019-09-03 23:24:35 +0700759}