1
0
mirror of https://github.com/golang/go synced 2024-11-24 07:00:13 -07:00

exp/template: fix endless loop

No progress was made in indirect() if the reflect.Value
was an non-nil and non-empty interface.

R=r, r
CC=golang-dev
https://golang.org/cl/4810060
This commit is contained in:
Robert Griesemer 2011-07-30 17:11:52 -07:00
parent bf184398f6
commit 7162f39fc3
2 changed files with 13 additions and 3 deletions

View File

@ -585,12 +585,12 @@ func (s *state) evalEmptyInterface(dot reflect.Value, n node) reflect.Value {
// We indirect through pointers and empty interfaces (only) because
// non-empty interfaces have methods we might need.
func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
if v.IsNil() {
return v, true
}
if v.Kind() == reflect.Ptr || v.NumMethod() == 0 {
v = v.Elem()
if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
break
}
}
return v, false

View File

@ -75,6 +75,13 @@ var tVal = &T{
Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X
}
// A non-empty interface.
type I interface {
Method0() string
}
var iVal I = tVal
// Helpers for creation.
func newInt(n int) *int {
p := new(int)
@ -344,6 +351,9 @@ var execTests = []execTest{
// Fixed bugs.
// Must separate dot and receiver; otherwise args are evaluated with dot set to variable.
{"bug0", "{{range .MSIone}}{{if $.Method1 .}}X{{end}}{{end}}", "X", tVal, true},
// Do not loop endlessly in indirect for non-empty interfaces.
// The bug appears with *interface only; this is supposed to fail (cannot invoke Method0), but terminate.
{"bug1", "{{.Method0}}", "", &iVal, false},
}
func zeroArgs() string {