mirror of
https://github.com/golang/go
synced 2024-11-25 09:27:57 -07:00
gc: fix complex move bug
R=ken2 CC=golang-dev https://golang.org/cl/4439044
This commit is contained in:
parent
de5616fbb4
commit
a12d70f60d
@ -21,7 +21,7 @@ void
|
|||||||
complexmove(Node *f, Node *t)
|
complexmove(Node *f, Node *t)
|
||||||
{
|
{
|
||||||
int ft, tt;
|
int ft, tt;
|
||||||
Node n1, n2, n3, n4;
|
Node n1, n2, n3, n4, t3, t4;
|
||||||
|
|
||||||
if(debug['g']) {
|
if(debug['g']) {
|
||||||
dump("\ncomplexmove-f", f);
|
dump("\ncomplexmove-f", f);
|
||||||
@ -54,8 +54,21 @@ complexmove(Node *f, Node *t)
|
|||||||
subnode(&n1, &n2, f);
|
subnode(&n1, &n2, f);
|
||||||
subnode(&n3, &n4, t);
|
subnode(&n3, &n4, t);
|
||||||
|
|
||||||
cgen(&n1, &n3);
|
// Copy fully into registers before doing stores,
|
||||||
cgen(&n2, &n4);
|
// in case the source and destination overlap.
|
||||||
|
// Might be picking up a complex128 from one
|
||||||
|
// location on the stack and writing it 8 bytes
|
||||||
|
// (half a complex128) later, in which case the
|
||||||
|
// first write would smash the source for the second read.
|
||||||
|
regalloc(&t3, types[tt+TFLOAT64-TCOMPLEX128], N);
|
||||||
|
regalloc(&t4, types[tt+TFLOAT64-TCOMPLEX128], N);
|
||||||
|
cgen(&n1, &t3);
|
||||||
|
cgen(&n2, &t4);
|
||||||
|
|
||||||
|
cgen(&t3, &n3);
|
||||||
|
cgen(&t4, &n4);
|
||||||
|
regfree(&t3);
|
||||||
|
regfree(&t4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
test/fixedbugs/bug329.go
Normal file
50
test/fixedbugs/bug329.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2011 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.
|
||||||
|
|
||||||
|
// Test that when moving a complex128 returned by one function
|
||||||
|
// into the argument position for another function, the right thing
|
||||||
|
// happens, even when the two positions half-overlap.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
type Value struct {
|
||||||
|
X interface{}
|
||||||
|
Y int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Struct struct {
|
||||||
|
X complex128
|
||||||
|
}
|
||||||
|
|
||||||
|
const magic = 1+2i
|
||||||
|
|
||||||
|
func (Value) Complex(x complex128) {
|
||||||
|
if x != magic {
|
||||||
|
println(x)
|
||||||
|
panic("bad complex magic")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func f(x *byte, y, z int) complex128 {
|
||||||
|
return magic
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Value) Struct(x Struct) {
|
||||||
|
if x.X != magic {
|
||||||
|
println(x.X)
|
||||||
|
panic("bad struct magic")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func f1(x *byte, y, z int) Struct {
|
||||||
|
return Struct{magic}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var v Value
|
||||||
|
v.Struct(f1(nil, 0, 0)) // ok
|
||||||
|
v.Complex(f(nil, 0, 0)) // used to fail
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user