OSDN Git Service

Update Go library to r60.3 release.
[pf3gnuchains/gcc-fork.git] / libgo / go / reflect / value.go
index 6675a9a..0d916e8 100644 (file)
@@ -829,14 +829,7 @@ func (v Value) CanInterface() bool {
        if iv.kind == Invalid {
                panic(&ValueError{"reflect.Value.CanInterface", iv.kind})
        }
-       // TODO(rsc): Check flagRO too.  Decide what to do about asking for
-       // interface for a value obtained via an unexported field.
-       // If the field were of a known type, say chan int or *sync.Mutex,
-       // the caller could interfere with the data after getting the
-       // interface.  But fmt.Print depends on being able to look.
-       // Now that reflect is more efficient the special cases in fmt
-       // might be less important.
-       return v.InternalMethod == 0
+       return v.InternalMethod == 0 && iv.flag&flagRO == 0
 }
 
 // Interface returns v's value as an interface{}.
@@ -844,22 +837,28 @@ func (v Value) CanInterface() bool {
 // (as opposed to Type.Method), Interface cannot return an
 // interface value, so it panics.
 func (v Value) Interface() interface{} {
-       return v.internal().Interface()
+       return valueInterface(v, true)
 }
 
-func (iv internalValue) Interface() interface{} {
+func valueInterface(v Value, safe bool) interface{} {
+       iv := v.internal()
+       return iv.valueInterface(safe)
+}
+
+func (iv internalValue) valueInterface(safe bool) interface{} {
        if iv.kind == 0 {
                panic(&ValueError{"reflect.Value.Interface", iv.kind})
        }
        if iv.method {
                panic("reflect.Value.Interface: cannot create interface value for method with bound receiver")
        }
-       /*
-               if v.flag()&noExport != 0 {
-                       panic("reflect.Value.Interface: cannot return value obtained from unexported struct field")
-               }
-       */
 
+       if safe && iv.flag&flagRO != 0 {
+               // Do not allow access to unexported values via Interface,
+               // 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")
+       }
        if iv.kind == Interface {
                // Special case: return the element inside the interface.
                // Won't recurse further because an interface cannot contain an interface.
@@ -1695,7 +1694,7 @@ func convertForAssignment(what string, addr unsafe.Pointer, dst Type, iv interna
                if addr == nil {
                        addr = unsafe.Pointer(new(interface{}))
                }
-               x := iv.Interface()
+               x := iv.valueInterface(false)
                if dst.NumMethod() == 0 {
                        *(*interface{})(addr) = x
                } else {