mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
cmd/gc: record &x[0] as taking address of x, if x is an array
Not recording the address being taken was causing the liveness analysis not to preserve x in the absence of direct references to x, which in turn was making the net test fail with GOGC=0. In addition to the test, this fixes a bug wherein GOGC=0 go test -short net crashed if liveness analysis was in use (like at tip, not like Go 1.2). TBR=ken2 CC=golang-codereviews https://golang.org/cl/64470043
This commit is contained in:
parent
8b6ef69e23
commit
1a3ee6794c
4 changed files with 40 additions and 2 deletions
|
@ -1452,6 +1452,7 @@ void walkstmt(Node **np);
|
|||
void walkstmtlist(NodeList *l);
|
||||
Node* conv(Node*, Type*);
|
||||
int candiscard(Node*);
|
||||
Node* outervalue(Node*);
|
||||
|
||||
/*
|
||||
* arch-specific ggen.c/gsubr.c/gobj.c/pgen.c/plive.c
|
||||
|
|
|
@ -721,7 +721,8 @@ reswitch:
|
|||
if(n->left->type == T)
|
||||
goto error;
|
||||
checklvalue(n->left, "take the address of");
|
||||
for(l=n->left; l->op == ODOT; l=l->left)
|
||||
r = outervalue(n->left);
|
||||
for(l = n->left; l != r; l = l->left)
|
||||
l->addrtaken = 1;
|
||||
if(l->orig != l && l->op == ONAME)
|
||||
fatal("found non-orig name node %N", l);
|
||||
|
|
|
@ -2205,7 +2205,7 @@ reorder3save(Node **np, NodeList *all, NodeList *stop, NodeList **early)
|
|||
* what's the outer value that a write to n affects?
|
||||
* outer value means containing struct or array.
|
||||
*/
|
||||
static Node*
|
||||
Node*
|
||||
outervalue(Node *n)
|
||||
{
|
||||
for(;;) {
|
||||
|
|
36
test/fixedbugs/bug483.go
Normal file
36
test/fixedbugs/bug483.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
// run
|
||||
|
||||
// Copyright 2014 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 for a garbage collection bug involving not
|
||||
// marking x as having its address taken by &x[0]
|
||||
// when x is an array value.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var x = [4]struct{ x, y interface{} }{
|
||||
{"a", "b"},
|
||||
{"c", "d"},
|
||||
{"e", "f"},
|
||||
{"g", "h"},
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
for _, z := range x {
|
||||
runtime.GC()
|
||||
fmt.Fprintf(&buf, "%s %s ", z.x.(string), z.y.(string))
|
||||
}
|
||||
|
||||
if buf.String() != "a b c d e f g h " {
|
||||
println("BUG wrong output\n", buf.String())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue