cmd/gc: fix initialization order involving method calls.

They were previously ignored when deciding order and
detecting dependency loops.
Fixes #3824.

R=rsc, golang-dev
CC=golang-dev, remy
https://golang.org/cl/6455055
This commit is contained in:
Rémy Oudompheng 2012-07-30 09:14:49 +02:00
parent 67d8a2d4c1
commit 6cbf35c172
3 changed files with 48 additions and 1 deletions

View file

@ -130,7 +130,12 @@ methodfunc(Type *f, Type *receiver)
out = list(out, d);
}
return functype(N, in, out);
t = functype(N, in, out);
if(f->nname) {
// Link to name of original method function.
t->nname = f->nname;
}
return t;
}
/*

View file

@ -36,6 +36,10 @@ init1(Node *n, NodeList **out)
init1(n->right, out);
for(l=n->list; l; l=l->next)
init1(l->n, out);
if(n->left && n->type && n->left->op == OTYPE && n->class == PFUNC) {
// Definitions for method expressions are stored in type->nname.
init1(n->type->nname, out);
}
if(n->op != ONAME)
return;
@ -170,6 +174,8 @@ init2(Node *n, NodeList **out)
if(n->op == OCLOSURE)
init2list(n->closure->nbody, out);
if(n->op == ODOTMETH)
init2(n->type->nname, out);
}
static void

36
test/fixedbugs/bug446.go Normal file
View file

@ -0,0 +1,36 @@
// run
// Copyright 2012 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.
// Issue 3824.
// Method calls are ignored when deciding initialization
// order.
package main
type T int
func (r T) Method1() int { return a }
func (r T) Method2() int { return b }
// dummy1 and dummy2 must be initialized after a and b.
var dummy1 = T(0).Method1()
var dummy2 = T.Method2(0)
// Use a function call to force generating code.
var a = identity(1)
var b = identity(2)
func identity(a int) int { return a }
func main() {
if dummy1 != 1 {
panic("dummy1 != 1")
}
if dummy2 != 2 {
panic("dummy2 != 2")
}
}