Patchwork libgo patch committed: Fix reflect.valueInterface

login
register
mail settings
Submitter Ian Taylor
Date Nov. 19, 2012, 5:34 a.m.
Message ID <mcrmwyexijm.fsf@google.com>
Download mbox | patch
Permalink /patch/199928/
State New
Headers show

Comments

Ian Taylor - Nov. 19, 2012, 5:34 a.m.
The gccgo frontend uses a slightly different representation for
interface values than the gc compiler: the gccgo frontend stores pointer
values directly, and all other values indirectly.  That requires some
changes in the reflect package.  There was a bug in those changes, which
showed up in that in some cases different reflect.Value values would
incorrectly point to the same underlying memory.  This patch fixes the
bug.  Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline and 4.7 branch.

Ian

Patch

diff -r 4bbe9e0d26e7 libgo/go/reflect/value.go
--- a/libgo/go/reflect/value.go	Sat Nov 17 23:53:21 2012 -0800
+++ b/libgo/go/reflect/value.go	Sun Nov 18 21:33:01 2012 -0800
@@ -342,7 +342,7 @@ 
 }
 
 // CallSlice calls the variadic function v with the input arguments in,
-// assigning the slice in[len(in)-1] to v's final variadic argument.  
+// assigning the slice in[len(in)-1] to v's final variadic argument.
 // For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]...).
 // Call panics if v's Kind is not Func or if v is not variadic.
 // It returns the output results as Values.
@@ -905,7 +905,7 @@ 
 
 	if safe && v.flag&flagRO != 0 {
 		// Do not allow access to unexported values via Interface,
-		// because they might be pointers that should not be 
+		// because they might be pointers that should not be
 		// writable or methods or function that should not be callable.
 		panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
 	}
@@ -928,7 +928,7 @@ 
 	eface.typ = v.typ.runtimeType()
 	eface.word = v.iword()
 
-	if v.flag&flagIndir != 0 && v.typ.size > ptrSize {
+	if v.flag&flagIndir != 0 && v.kind() != Ptr && v.kind() != UnsafePointer {
 		// eface.word is a pointer to the actual data,
 		// which might be changed.  We need to return
 		// a pointer to unchanging data, so make a copy.
@@ -1777,7 +1777,7 @@ 
 		default:
 			panic("reflect.Select: invalid Dir")
 
-		case SelectDefault: // default	
+		case SelectDefault: // default
 			if haveDefault {
 				panic("reflect.Select: multiple default cases")
 			}