1// build -goexperiment regabi,regabiargs 2 3// Copyright 2021 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. 6 7package main 8 9import ( 10 "fmt" 11 "os" 12 "reflect" 13) 14 15func main() { 16 // Only print if there is a problem 17 Caller2() 18 if FailCount != 0 { 19 fmt.Fprintf(os.Stderr, "FAILURES: %d\n", FailCount) 20 os.Exit(2) 21 } 22} 23 24var ParamFailCount int 25 26var ReturnFailCount int 27 28var FailCount int 29 30var Mode string 31 32type UtilsType int 33 34//go:noinline 35func NoteFailure(cm int, pidx int, fidx int, pkg string, pref string, parmNo int, isret bool, _ uint64) { 36 if isret { 37 if ParamFailCount != 0 { 38 return 39 } 40 ReturnFailCount++ 41 } else { 42 ParamFailCount++ 43 } 44 fmt.Fprintf(os.Stderr, "Error: fail %s |%d|%d|%d| =%s.Test%d= %s %d\n", Mode, cm, pidx, fidx, pkg, fidx, pref, parmNo) 45 46 if ParamFailCount+FailCount+ReturnFailCount > 9999 { 47 os.Exit(1) 48 } 49} 50 51//go:noinline 52func NoteFailureElem(cm int, pidx int, fidx int, pkg string, pref string, parmNo int, elem int, isret bool, _ uint64) { 53 54 if isret { 55 if ParamFailCount != 0 { 56 return 57 } 58 ReturnFailCount++ 59 } else { 60 ParamFailCount++ 61 } 62 fmt.Fprintf(os.Stderr, "Error: fail %s |%d|%d|%d| =%s.Test%d= %s %d elem %d\n", Mode, cm, pidx, fidx, pkg, fidx, pref, parmNo, elem) 63 64 if ParamFailCount+FailCount+ReturnFailCount > 9999 { 65 os.Exit(1) 66 } 67} 68 69func BeginFcn() { 70 ParamFailCount = 0 71 ReturnFailCount = 0 72} 73 74func EndFcn() { 75 FailCount += ParamFailCount 76 FailCount += ReturnFailCount 77} 78 79func Caller2() { 80 BeginFcn() 81 c0 := StructF2S0{F0: ArrayF2S1E1{New_3(float64(-0.4418990509835844))}} 82 c1 := ArrayF2S2E1{StructF2S1{ /* _: "(z̽|" */ F1: ""}} 83 c2 := int16(4162) 84 c3 := float32(-7.667096e+37) 85 c4 := int64(3202175648847048679) 86 var p0 ArrayF2S0E0 87 p0 = ArrayF2S0E0{} 88 var p1 uint8 89 p1 = uint8(57) 90 var p2 uint16 91 p2 = uint16(10920) 92 var p3 float64 93 p3 = float64(-1.597256501942112) 94 Mode = "" 95 // 5 returns 4 params 96 r0, r1, r2, r3, r4 := Test2(p0, p1, p2, p3) 97 if !EqualStructF2S0(r0, c0) { 98 NoteFailure(9, 42, 2, "genChecker42", "return", 0, true, uint64(0)) 99 } 100 if r1 != c1 { 101 NoteFailure(9, 42, 2, "genChecker42", "return", 1, true, uint64(0)) 102 } 103 if r2 != c2 { 104 NoteFailure(9, 42, 2, "genChecker42", "return", 2, true, uint64(0)) 105 } 106 if r3 != c3 { 107 NoteFailure(9, 42, 2, "genChecker42", "return", 3, true, uint64(0)) 108 } 109 if r4 != c4 { 110 NoteFailure(9, 42, 2, "genChecker42", "return", 4, true, uint64(0)) 111 } 112 // same call via reflection 113 Mode = "reflect" 114 rc := reflect.ValueOf(Test2) 115 rvslice := rc.Call([]reflect.Value{reflect.ValueOf(p0), reflect.ValueOf(p1), reflect.ValueOf(p2), reflect.ValueOf(p3)}) 116 rr0i := rvslice[0].Interface() 117 rr0v := rr0i.(StructF2S0) 118 if !EqualStructF2S0(rr0v, c0) { 119 NoteFailure(9, 42, 2, "genChecker42", "return", 0, true, uint64(0)) 120 } 121 rr1i := rvslice[1].Interface() 122 rr1v := rr1i.(ArrayF2S2E1) 123 if rr1v != c1 { 124 NoteFailure(9, 42, 2, "genChecker42", "return", 1, true, uint64(0)) 125 } 126 rr2i := rvslice[2].Interface() 127 rr2v := rr2i.(int16) 128 if rr2v != c2 { 129 NoteFailure(9, 42, 2, "genChecker42", "return", 2, true, uint64(0)) 130 } 131 rr3i := rvslice[3].Interface() 132 rr3v := rr3i.(float32) 133 if rr3v != c3 { 134 NoteFailure(9, 42, 2, "genChecker42", "return", 3, true, uint64(0)) 135 } 136 rr4i := rvslice[4].Interface() 137 rr4v := rr4i.(int64) 138 if rr4v != c4 { 139 NoteFailure(9, 42, 2, "genChecker42", "return", 4, true, uint64(0)) 140 } 141 EndFcn() 142} 143 144type StructF0S0 struct { 145} 146 147type ArrayF0S0E2 [2]int16 148 149type ArrayF0S1E1 [1]StructF0S0 150 151type StructF1S0 struct { 152 F0 StructF1S1 153 _ ArrayF1S0E4 154} 155 156type StructF1S1 struct { 157} 158 159type StructF1S2 struct { 160 F0 uint32 161 F1 uint8 162 F2 string 163 F3 string 164 F4 ArrayF1S1E1 165} 166 167type StructF1S3 struct { 168 F0 float64 169} 170 171type StructF1S4 struct { 172 _ int32 173 F1 float32 174} 175 176type StructF1S5 struct { 177 F0 uint16 178} 179 180type StructF1S6 struct { 181 F0 uint8 182 F1 uint32 183} 184 185type ArrayF1S0E4 [4]float64 186 187type ArrayF1S1E1 [1]StructF1S3 188 189type ArrayF1S2E2 [2]StructF1S4 190 191type ArrayF1S3E2 [2]StructF1S5 192 193type ArrayF1S4E4 [4]ArrayF1S5E3 194 195type ArrayF1S5E3 [3]string 196 197type ArrayF1S6E1 [1]float64 198 199type StructF2S0 struct { 200 F0 ArrayF2S1E1 201} 202 203// equal func for StructF2S0 204//go:noinline 205func EqualStructF2S0(left StructF2S0, right StructF2S0) bool { 206 return EqualArrayF2S1E1(left.F0, right.F0) 207} 208 209type StructF2S1 struct { 210 _ string 211 F1 string 212} 213 214type ArrayF2S0E0 [0]int8 215 216type ArrayF2S1E1 [1]*float64 217 218// equal func for ArrayF2S1E1 219//go:noinline 220func EqualArrayF2S1E1(left ArrayF2S1E1, right ArrayF2S1E1) bool { 221 return *left[0] == *right[0] 222} 223 224type ArrayF2S2E1 [1]StructF2S1 225 226// 5 returns 4 params 227//go:registerparams 228//go:noinline 229func Test2(p0 ArrayF2S0E0, p1 uint8, _ uint16, p3 float64) (r0 StructF2S0, r1 ArrayF2S2E1, r2 int16, r3 float32, r4 int64) { 230 // consume some stack space, so as to trigger morestack 231 var pad [16]uint64 232 pad[FailCount&0x1]++ 233 rc0 := StructF2S0{F0: ArrayF2S1E1{New_3(float64(-0.4418990509835844))}} 234 rc1 := ArrayF2S2E1{StructF2S1{ /* _: "(z̽|" */ F1: ""}} 235 rc2 := int16(4162) 236 rc3 := float32(-7.667096e+37) 237 rc4 := int64(3202175648847048679) 238 p1f0c := uint8(57) 239 if p1 != p1f0c { 240 NoteFailureElem(9, 42, 2, "genChecker42", "parm", 1, 0, false, pad[0]) 241 return 242 } 243 _ = uint16(10920) 244 p3f0c := float64(-1.597256501942112) 245 if p3 != p3f0c { 246 NoteFailureElem(9, 42, 2, "genChecker42", "parm", 3, 0, false, pad[0]) 247 return 248 } 249 defer func(p0 ArrayF2S0E0, p1 uint8) { 250 // check parm passed 251 // check parm passed 252 if p1 != p1f0c { 253 NoteFailureElem(9, 42, 2, "genChecker42", "parm", 1, 0, false, pad[0]) 254 return 255 } 256 // check parm captured 257 if p3 != p3f0c { 258 NoteFailureElem(9, 42, 2, "genChecker42", "parm", 3, 0, false, pad[0]) 259 return 260 } 261 }(p0, p1) 262 263 return rc0, rc1, rc2, rc3, rc4 264 // 0 addr-taken params, 0 addr-taken returns 265} 266 267//go:noinline 268func New_3(i float64) *float64 { 269 x := new(float64) 270 *x = i 271 return x 272} 273