golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/go/ssa/interp/testdata/forvarlifetime_old.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.19
     6  
     7  // goversion can be pinned to anything strictly before 1.22.
     8  
     9  package main
    10  
    11  import (
    12  	"reflect"
    13  )
    14  
    15  func main() {
    16  	test_init()
    17  	bound()
    18  	manyvars()
    19  	nocond()
    20  	nopost()
    21  	address_sequences()
    22  	post_escapes()
    23  
    24  	// Clones from cmd/compile/internal/loopvar/testdata .
    25  	for_complicated_esc_address()
    26  	for_esc_address()
    27  	for_esc_closure()
    28  	for_esc_method()
    29  }
    30  
    31  // pre-go1.22 all of i will have the same address and the value of 6.
    32  var same = func(m, n int) []*int {
    33  	var r []*int
    34  	for i := m; i <= n; i++ {
    35  		r = append(r, &i)
    36  	}
    37  	return r
    38  }(3, 5)
    39  
    40  func test_init() {
    41  	if len(same) != 3 {
    42  		panic(same)
    43  	}
    44  	for i := range same {
    45  		for j := range same {
    46  			if !(same[i] == same[j]) {
    47  				panic(same)
    48  			}
    49  		}
    50  	}
    51  	for i := range same {
    52  		if *(same[i]) != 6 {
    53  			panic(same)
    54  		}
    55  	}
    56  }
    57  
    58  func bound() {
    59  	b := func(k int) func() int {
    60  		var f func() int
    61  		for i := 0; i < k; i++ {
    62  			f = func() int { return i } // shared address will equal k.
    63  		}
    64  		return f
    65  	}
    66  
    67  	if got := b(0); got != nil {
    68  		panic(got)
    69  	}
    70  	if got := b(5); got() != 5 {
    71  		panic(got())
    72  	}
    73  }
    74  
    75  func manyvars() {
    76  	// Tests declaring many variables and having one in the middle escape.
    77  	var f func() int
    78  	for i, j, k, l, m, n, o, p := 7, 6, 5, 4, 3, 2, 1, 0; p < 6; l, p = l+1, p+1 {
    79  		_, _, _, _, _, _, _, _ = i, j, k, l, m, n, o, p
    80  		f = func() int { return l } // address *after* post updates l
    81  	}
    82  	if f() != 10 { // l == p+4
    83  		panic(f())
    84  	}
    85  }
    86  
    87  func nocond() {
    88  	var c, b, e *int
    89  	for p := 0; ; p++ {
    90  		if p%7 == 0 {
    91  			c = &p
    92  			continue
    93  		} else if p == 20 {
    94  			b = &p
    95  			break
    96  		}
    97  		e = &p
    98  	}
    99  
   100  	if *c != 20 {
   101  		panic(c)
   102  	}
   103  	if *b != 20 {
   104  		panic(b)
   105  	}
   106  	if *e != 20 {
   107  		panic(e)
   108  	}
   109  }
   110  
   111  func nopost() {
   112  	var first, last *int
   113  	for p := 0; p < 20; {
   114  		if first == nil {
   115  			first = &p
   116  		}
   117  		last = &p
   118  
   119  		p++
   120  	}
   121  
   122  	if *first != 20 {
   123  		panic(first)
   124  	}
   125  	if *last != 20 {
   126  		panic(last)
   127  	}
   128  }
   129  
   130  func address_sequences() {
   131  	var c, b, p []*int
   132  
   133  	cond := func(x *int) bool {
   134  		c = append(c, x)
   135  		return *x < 5
   136  	}
   137  	body := func(x *int) {
   138  		b = append(b, x)
   139  	}
   140  	post := func(x *int) {
   141  		p = append(p, x)
   142  		(*x)++
   143  	}
   144  	for i := 0; cond(&i); post(&i) {
   145  		body(&i)
   146  	}
   147  
   148  	if c[0] != c[1] {
   149  		panic(c)
   150  	}
   151  
   152  	if !reflect.DeepEqual(c[:5], b) {
   153  		panic(c)
   154  	}
   155  
   156  	if !reflect.DeepEqual(c[1:], p) {
   157  		panic(c)
   158  	}
   159  
   160  	if !reflect.DeepEqual(b[1:], p[:4]) {
   161  		panic(b)
   162  	}
   163  }
   164  
   165  func post_escapes() {
   166  	var p []*int
   167  	post := func(x *int) {
   168  		p = append(p, x)
   169  		(*x)++
   170  	}
   171  
   172  	for i := 0; i < 5; post(&i) {
   173  	}
   174  
   175  	var got []int
   176  	for _, x := range p {
   177  		got = append(got, *x)
   178  	}
   179  	if want := []int{5, 5, 5, 5, 5}; !reflect.DeepEqual(got, want) {
   180  		panic(got)
   181  	}
   182  }
   183  
   184  func for_complicated_esc_address() {
   185  	// Clone of for_complicated_esc_adress.go
   186  	ss, sa := shared(23)
   187  	ps, pa := private(23)
   188  	es, ea := experiment(23)
   189  
   190  	if ss != ps || ss != es || sa != ea || pa != 188 {
   191  		println("shared s, a", ss, sa, "; private, s, a", ps, pa, "; experiment s, a", es, ea)
   192  		panic("for_complicated_esc_address")
   193  	}
   194  }
   195  
   196  func experiment(x int) (int, int) {
   197  	sum := 0
   198  	var is []*int
   199  	for i := x; i != 1; i = i / 2 {
   200  		for j := 0; j < 10; j++ {
   201  			if i == j { // 10 skips
   202  				continue
   203  			}
   204  			sum++
   205  		}
   206  		i = i*3 + 1
   207  		if i&1 == 0 {
   208  			is = append(is, &i)
   209  			for i&2 == 0 {
   210  				i = i >> 1
   211  			}
   212  		} else {
   213  			i = i + i
   214  		}
   215  	}
   216  
   217  	asum := 0
   218  	for _, pi := range is {
   219  		asum += *pi
   220  	}
   221  
   222  	return sum, asum
   223  }
   224  
   225  func private(x int) (int, int) {
   226  	sum := 0
   227  	var is []*int
   228  	I := x
   229  	for ; I != 1; I = I / 2 {
   230  		i := I
   231  		for j := 0; j < 10; j++ {
   232  			if i == j { // 10 skips
   233  				I = i
   234  				continue
   235  			}
   236  			sum++
   237  		}
   238  		i = i*3 + 1
   239  		if i&1 == 0 {
   240  			is = append(is, &i)
   241  			for i&2 == 0 {
   242  				i = i >> 1
   243  			}
   244  		} else {
   245  			i = i + i
   246  		}
   247  		I = i
   248  	}
   249  
   250  	asum := 0
   251  	for _, pi := range is {
   252  		asum += *pi
   253  	}
   254  
   255  	return sum, asum
   256  }
   257  
   258  func shared(x int) (int, int) {
   259  	sum := 0
   260  	var is []*int
   261  	i := x
   262  	for ; i != 1; i = i / 2 {
   263  		for j := 0; j < 10; j++ {
   264  			if i == j { // 10 skips
   265  				continue
   266  			}
   267  			sum++
   268  		}
   269  		i = i*3 + 1
   270  		if i&1 == 0 {
   271  			is = append(is, &i)
   272  			for i&2 == 0 {
   273  				i = i >> 1
   274  			}
   275  		} else {
   276  			i = i + i
   277  		}
   278  	}
   279  
   280  	asum := 0
   281  	for _, pi := range is {
   282  		asum += *pi
   283  	}
   284  	return sum, asum
   285  }
   286  
   287  func for_esc_address() {
   288  	// Clone of for_esc_address.go
   289  	sum := 0
   290  	var is []*int
   291  	for i := 0; i < 10; i++ {
   292  		for j := 0; j < 10; j++ {
   293  			if i == j { // 10 skips
   294  				continue
   295  			}
   296  			sum++
   297  		}
   298  		if i&1 == 0 {
   299  			is = append(is, &i)
   300  		}
   301  	}
   302  
   303  	bug := false
   304  	if sum != 100-10 {
   305  		println("wrong sum, expected", 90, ", saw", sum)
   306  		bug = true
   307  	}
   308  	if len(is) != 5 {
   309  		println("wrong iterations, expected ", 5, ", saw", len(is))
   310  		bug = true
   311  	}
   312  	sum = 0
   313  	for _, pi := range is {
   314  		sum += *pi
   315  	}
   316  	if sum != 10+10+10+10+10 {
   317  		println("wrong sum, expected ", 50, ", saw ", sum)
   318  		bug = true
   319  	}
   320  	if bug {
   321  		panic("for_esc_address")
   322  	}
   323  }
   324  
   325  func for_esc_closure() {
   326  	// Clone of for_esc_closure.go
   327  	var is []func() int
   328  	sum := 0
   329  	for i := 0; i < 10; i++ {
   330  		for j := 0; j < 10; j++ {
   331  			if i == j { // 10 skips
   332  				continue
   333  			}
   334  			sum++
   335  		}
   336  		if i&1 == 0 {
   337  			is = append(is, func() int {
   338  				if i%17 == 15 {
   339  					i++
   340  				}
   341  				return i
   342  			})
   343  		}
   344  	}
   345  
   346  	bug := false
   347  	if sum != 100-10 {
   348  		println("wrong sum, expected ", 90, ", saw", sum)
   349  		bug = true
   350  	}
   351  	if len(is) != 5 {
   352  		println("wrong iterations, expected ", 5, ", saw", len(is))
   353  		bug = true
   354  	}
   355  	sum = 0
   356  	for _, f := range is {
   357  		sum += f()
   358  	}
   359  	if sum != 10+10+10+10+10 {
   360  		println("wrong sum, expected ", 50, ", saw ", sum)
   361  		bug = true
   362  	}
   363  	if bug {
   364  		panic("for_esc_closure")
   365  	}
   366  }
   367  
   368  type I int
   369  
   370  func (x *I) method() int {
   371  	return int(*x)
   372  }
   373  
   374  func for_esc_method() {
   375  	// Clone of for_esc_method.go
   376  	sum := 0
   377  	var is []func() int
   378  	for i := I(0); int(i) < 10; i++ {
   379  		for j := 0; j < 10; j++ {
   380  			if int(i) == j { // 10 skips
   381  				continue
   382  			}
   383  			sum++
   384  		}
   385  		if i&1 == 0 {
   386  			is = append(is, i.method)
   387  		}
   388  	}
   389  
   390  	bug := false
   391  	if sum != 100-10 {
   392  		println("wrong sum, expected ", 90, ", saw ", sum)
   393  		bug = true
   394  	}
   395  	if len(is) != 5 {
   396  		println("wrong iterations, expected ", 5, ", saw", len(is))
   397  		bug = true
   398  	}
   399  	sum = 0
   400  	for _, m := range is {
   401  		sum += m()
   402  	}
   403  	if sum != 10+10+10+10+10 {
   404  		println("wrong sum, expected ", 50, ", saw ", sum)
   405  		bug = true
   406  	}
   407  	if bug {
   408  		panic("for_esc_method")
   409  	}
   410  }