// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// Test to make sure spills of cast-shortened values
// don't end up spilling the pre-shortened size instead
// of the post-shortened size.
import (
"runtime"
"testing"
)
var data1 [26]int32
var data2 [26]int64
func init() {
for i := 0; i < 26; i++ {
// If we spill all 8 bytes of this datum, the 1 in the high-order 4 bytes
// will overwrite some other variable in the stack frame.
data2[i] = 0x100000000
}
}
func foo() int32 {
var a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z int32
if always {
a = data1[0]
b = data1[1]
c = data1[2]
d = data1[3]
e = data1[4]
f = data1[5]
g = data1[6]
h = data1[7]
i = data1[8]
j = data1[9]
k = data1[10]
l = data1[11]
m = data1[12]
n = data1[13]
o = data1[14]
p = data1[15]
q = data1[16]
r = data1[17]
s = data1[18]
t = data1[19]
u = data1[20]
v = data1[21]
w = data1[22]
x = data1[23]
y = data1[24]
z = data1[25]
} else {
a = int32(data2[0])
b = int32(data2[1])
c = int32(data2[2])
d = int32(data2[3])
e = int32(data2[4])
f = int32(data2[5])
g = int32(data2[6])
h = int32(data2[7])
i = int32(data2[8])
j = int32(data2[9])
k = int32(data2[10])
l = int32(data2[11])
m = int32(data2[12])
n = int32(data2[13])
o = int32(data2[14])
p = int32(data2[15])
q = int32(data2[16])
r = int32(data2[17])
s = int32(data2[18])
t = int32(data2[19])
u = int32(data2[20])
v = int32(data2[21])
w = int32(data2[22])
x = int32(data2[23])
y = int32(data2[24])
z = int32(data2[25])
}
// Lots of phis of the form phi(int32,int64) of type int32 happen here.
// Some will be stack phis. For those stack phis, make sure the spill
// of the second argument uses the phi's width (4 bytes), not its width
// (8 bytes). Otherwise, a random stack slot gets clobbered.
runtime.Gosched()
return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z
}
func TestPhi(t *testing.T) {
want := int32(0)
got := foo()
if got != want {
t.Fatalf("want %d, got %d\n", want, got)
}
}
|