mirror of
https://github.com/golang/go
synced 2024-11-24 06:50:17 -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:
parent
bf184398f6
commit
7162f39fc3
@ -585,12 +585,12 @@ func (s *state) evalEmptyInterface(dot reflect.Value, n node) reflect.Value {
|
|||||||
// We indirect through pointers and empty interfaces (only) because
|
// We indirect through pointers and empty interfaces (only) because
|
||||||
// non-empty interfaces have methods we might need.
|
// non-empty interfaces have methods we might need.
|
||||||
func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
|
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() {
|
if v.IsNil() {
|
||||||
return v, true
|
return v, true
|
||||||
}
|
}
|
||||||
if v.Kind() == reflect.Ptr || v.NumMethod() == 0 {
|
if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
|
||||||
v = v.Elem()
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v, false
|
return v, false
|
||||||
|
@ -75,6 +75,13 @@ var tVal = &T{
|
|||||||
Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X
|
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.
|
// Helpers for creation.
|
||||||
func newInt(n int) *int {
|
func newInt(n int) *int {
|
||||||
p := new(int)
|
p := new(int)
|
||||||
@ -344,6 +351,9 @@ var execTests = []execTest{
|
|||||||
// Fixed bugs.
|
// Fixed bugs.
|
||||||
// Must separate dot and receiver; otherwise args are evaluated with dot set to variable.
|
// 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},
|
{"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 {
|
func zeroArgs() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user