Skip to content

Commit

Permalink
reflect: handling flagIndir in DeepEqual potential cycles
Browse files Browse the repository at this point in the history
Fixes golang#39607

Change-Id: Ia7e597e0da8a193a25382cc633a1c6080b4f7cbf
Reviewed-on: https://go-review.googlesource.com/c/go/+/238361
Run-TryBot: Ian Lance Taylor <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Keith Randall <[email protected]>
  • Loading branch information
ianlancetaylor committed Jun 18, 2020
1 parent 84baf41 commit d872bbc
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/reflect/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,11 @@ var loop1, loop2 Loop
var loopy1, loopy2 Loopy
var cycleMap1, cycleMap2, cycleMap3 map[string]interface{}

type structWithSelfPtr struct {
p *structWithSelfPtr
s string
}

func init() {
loop1 = &loop2
loop2 = &loop1
Expand Down Expand Up @@ -880,6 +885,7 @@ var deepEqualTests = []DeepEqualTest{
{[]float64{math.NaN()}, self{}, true},
{map[float64]float64{math.NaN(): 1}, map[float64]float64{1: 2}, false},
{map[float64]float64{math.NaN(): 1}, self{}, true},
{&structWithSelfPtr{p: &structWithSelfPtr{s: "a"}}, &structWithSelfPtr{p: &structWithSelfPtr{s: "b"}}, false},

// Nil vs empty: not the same.
{[]int{}, []int(nil), false},
Expand Down
16 changes: 14 additions & 2 deletions src/reflect/deepequal.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,20 @@ func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool {
}

if hard(v1, v2) {
addr1 := v1.ptr
addr2 := v2.ptr
// For a Ptr or Map value, we need to check flagIndir,
// which we do by calling the pointer method.
// For Slice or Interface, flagIndir is always set,
// and using v.ptr suffices.
ptrval := func(v Value) unsafe.Pointer {
switch v.Kind() {
case Ptr, Map:
return v.pointer()
default:
return v.ptr
}
}
addr1 := ptrval(v1)
addr2 := ptrval(v2)
if uintptr(addr1) > uintptr(addr2) {
// Canonicalize order to reduce number of entries in visited.
// Assumes non-moving garbage collector.
Expand Down

0 comments on commit d872bbc

Please sign in to comment.