1
0
mirror of https://github.com/golang/go synced 2024-11-11 20:40:21 -07:00

cmd/gc: check for initialization cycles in method values

Fixes #7960.

LGTM=rsc
R=rsc
CC=golang-codereviews, gri
https://golang.org/cl/159800045
This commit is contained in:
Chris Manghane 2014-10-14 19:12:10 -07:00
parent e9ecd4aec5
commit fe8f799ef7
27 changed files with 539 additions and 1 deletions

View File

@ -207,7 +207,7 @@ init2(Node *n, NodeList **out)
if(n->op == OCLOSURE)
init2list(n->closure->nbody, out);
if(n->op == ODOTMETH)
if(n->op == ODOTMETH || n->op == OCALLPART)
init2(n->type->nname, out);
}

View File

@ -0,0 +1,16 @@
// errorcheck
// 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.
// Check for cycles in a function value.
package funcvalue
func fx() int {
_ = x
return 0
}
var x = fx // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,16 @@
// errorcheck
// 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.
// Check for cycles in a function call.
package funccall
func fx() int {
_ = x
return 0
}
var x = fx() // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in a method expression.
package methexpr
type T int
func (T) m() int {
_ = x
return 0
}
var x = T.m // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in a method expression call.
package methexprcall
type T int
func (T) m() int {
_ = x
return 0
}
var x = T.m(0) // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in the method value of a value literal.
package litmethvalue
type T int
func (T) m() int {
_ = x
return 0
}
var x = T(0).m // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in the method call of a value literal.
package litmethcall
type T int
func (T) m() int {
_ = x
return 0
}
var x = T(0).m() // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,20 @@
// errorcheck
// 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.
// Check for cycles in an embedded method expression.
package embedmethexpr
type T int
func (T) m() int {
_ = x
return 0
}
type E struct{ T }
var x = E.m // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,20 @@
// errorcheck
// 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.
// Check for cycles when calling an embedded method expression.
package embedmethexprcall
type T int
func (T) m() int {
_ = x
return 0
}
type E struct{ T }
var x = E.m(E{0}) // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,20 @@
// errorcheck
// 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.
// Check for cycles in an embedded struct literal's method value.
package embedlitmethvalue
type T int
func (T) m() int {
_ = x
return 0
}
type E struct{ T }
var x = E{}.m // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,20 @@
// errorcheck
// 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.
// Check for cycles in an embedded struct literal's method call.
package embedlitmethcall
type T int
func (T) m() int {
_ = x
return 0
}
type E struct{ T }
var x = E{}.m() // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,21 @@
// errorcheck
// 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.
// Check for cycles in a method value.
package methvalue
type T int
func (T) m() int {
_ = x
return 0
}
var (
t T
x = t.m // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,21 @@
// errorcheck
// 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.
// Check for cycles in a method call.
package methcall
type T int
func (T) m() int {
_ = x
return 0
}
var (
t T
x = t.m() // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,25 @@
// errorcheck
// 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.
// Check for cycles in the method value of a value returned from a function call.
package funcmethvalue
type T int
func (T) m() int {
_ = x
return 0
}
func f() T {
return T(0)
}
var (
t T
x = f().m // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,25 @@
// errorcheck
// 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.
// Check for cycles in the method call of a value returned from a function call.
package funcmethcall
type T int
func (T) m() int {
_ = x
return 0
}
func f() T {
return T(0)
}
var (
t T
x = f().m() // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,23 @@
// errorcheck
// 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.
// Check for cycles in an embedded struct's method value.
package embedmethvalue
type T int
func (T) m() int {
_ = x
return 0
}
type E struct{ T }
var (
e E
x = e.m // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,23 @@
// errorcheck
// 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.
// Check for cycles in an embedded struct's method call.
package embedmethcall
type T int
func (T) m() int {
_ = x
return 0
}
type E struct{ T }
var (
e E
x = e.m() // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,28 @@
// errorcheck
// 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.
// Check for cycles in the method value of an embedded struct returned
// from a function call.
package funcembedmethvalue
type T int
func (T) m() int {
_ = x
return 0
}
func g() E {
return E{0}
}
type E struct{ T }
var (
e E
x = g().m // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,28 @@
// errorcheck
// 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.
// Check for cycles in the method call of an embedded struct returned
// from a function call.
package funcembedmethcall
type T int
func (T) m() int {
_ = x
return 0
}
func g() E {
return E{0}
}
type E struct{ T }
var (
e E
x = g().m() // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in a pointer method expression.
package ptrmethexpr
type T int
func (*T) pm() int {
_ = x
return 0
}
var x = (*T).pm // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in the call of a pointer method expression.
package ptrmethexprcall
type T int
func (*T) pm() int {
_ = x
return 0
}
var x = (*T).pm(nil) // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in a pointer literal's method value.
package ptrlitmethvalue
type T int
func (*T) pm() int {
_ = x
return 0
}
var x = (*T)(nil).pm // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,18 @@
// errorcheck
// 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.
// Check for cycles in a pointer literal's method call.
package ptrlitmethcall
type T int
func (*T) pm() int {
_ = x
return 0
}
var x = (*T)(nil).pm() // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,21 @@
// errorcheck
// 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.
// Check for cycles in a pointer value's method value.
package ptrmethvalue
type T int
func (*T) pm() int {
_ = x
return 0
}
var (
p *T
x = p.pm // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,21 @@
// errorcheck
// 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.
// Check for cycles in a pointer value's method call.
package ptrmethcall
type T int
func (*T) pm() int {
_ = x
return 0
}
var (
p *T
x = p.pm() // ERROR "initialization loop|depends upon itself"
)

View File

@ -0,0 +1,23 @@
// errorcheck
// 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.
// Check for cycles in the method value of a pointer value returned
// from a function call.
package funcptrmethvalue
type T int
func (*T) pm() int {
_ = x
return 0
}
func pf() *T {
return nil
}
var x = pf().pm // ERROR "initialization loop|depends upon itself"

View File

@ -0,0 +1,23 @@
// errorcheck
// 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.
// Check for cycles in the method call of a pointer value returned
// from a function call.
package funcptrmethcall
type T int
func (*T) pm() int {
_ = x
return 0
}
func pf() *T {
return nil
}
var x = pf().pm() // ERROR "initialization loop|depends upon itself"