gc: fix zero-length struct eval

Fixes #2232.

R=ken2
CC=golang-dev
https://golang.org/cl/4960054
This commit is contained in:
Russ Cox 2011-09-05 15:31:22 -04:00
parent d5e24b6975
commit 919cb2ec7c
4 changed files with 63 additions and 10 deletions

View file

@ -1201,8 +1201,6 @@ sgen(Node *n, Node *res, int32 w)
dump("r", n);
dump("res", res);
}
if(w == 0)
return;
if(w < 0)
fatal("sgen copy %d", w);
if(n->ullman >= UINF && res->ullman >= UINF)
@ -1210,6 +1208,15 @@ sgen(Node *n, Node *res, int32 w)
if(n->type == T)
fatal("sgen: missing type");
if(w == 0) {
// evaluate side effects only.
regalloc(&dst, types[tptr], N);
agen(res, &dst);
agen(n, &dst);
regfree(&dst);
return;
}
// determine alignment.
// want to avoid unaligned access, so have to use
// smaller operations for less aligned types.

View file

@ -1029,11 +1029,9 @@ sgen(Node *n, Node *ns, int32 w)
dump("r", n);
dump("res", ns);
}
if(w == 0)
return;
if(n->ullman >= UINF && ns->ullman >= UINF) {
if(n->ullman >= UINF && ns->ullman >= UINF)
fatal("sgen UINF");
}
if(w < 0)
fatal("sgen copy %d", w);
@ -1041,6 +1039,15 @@ sgen(Node *n, Node *ns, int32 w)
if(w == 16)
if(componentgen(n, ns))
return;
if(w == 0) {
// evaluate side effects only
regalloc(&nodr, types[tptr], N);
agen(ns, &nodr);
agen(n, &nodr);
regfree(&nodr);
return;
}
// offset on the stack
osrc = stkof(n);

View file

@ -1136,15 +1136,20 @@ sgen(Node *n, Node *res, int32 w)
dump("r", n);
dump("res", res);
}
if(w == 0)
return;
if(n->ullman >= UINF && res->ullman >= UINF) {
if(n->ullman >= UINF && res->ullman >= UINF)
fatal("sgen UINF");
}
if(w < 0)
fatal("sgen copy %d", w);
if(w == 0) {
// evaluate side effects only.
tempname(&tdst, types[tptr]);
agen(res, &tdst);
agen(n, &tdst);
return;
}
// offset on the stack
osrc = stkof(n);
odst = stkof(res);

34
test/struct0.go Normal file
View file

@ -0,0 +1,34 @@
// $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.
// zero length structs.
// used to not be evaluated.
// issue 2232.
package main
func recv(c chan interface{}) struct{} {
return (<-c).(struct{})
}
var m = make(map[interface{}]int)
func recv1(c chan interface{}) {
defer rec()
m[(<-c).(struct{})] = 0
}
func rec() {
recover()
}
func main() {
c := make(chan interface{})
go recv(c)
c <- struct{}{}
go recv1(c)
c <- struct{}{}
}