go.tools/go/types: unsafe.Offsetof must deref named pointers to structs
R=adonovan CC=golang-dev https://golang.org/cl/11889043
This commit is contained in:
parent
4da31df1c8
commit
bf6a1e674e
|
|
@ -340,7 +340,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, bin *Builtin) {
|
||||||
if x.mode == invalid {
|
if x.mode == invalid {
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
base, _ := deref(x.typ)
|
base := derefStructPtr(x.typ)
|
||||||
sel := arg.Sel.Name
|
sel := arg.Sel.Name
|
||||||
obj, index, indirect := LookupFieldOrMethod(base, check.pkg, arg.Sel.Name)
|
obj, index, indirect := LookupFieldOrMethod(base, check.pkg, arg.Sel.Name)
|
||||||
switch obj.(type) {
|
switch obj.(type) {
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,7 @@ func MissingMethod(typ Type, T *Interface) (method *Func, wrongType bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deref dereferences typ if it is a pointer and returns its base and true.
|
// deref dereferences typ if it is a *Pointer and returns its base and true.
|
||||||
// Otherwise it returns (typ, false).
|
// Otherwise it returns (typ, false).
|
||||||
func deref(typ Type) (Type, bool) {
|
func deref(typ Type) (Type, bool) {
|
||||||
if p, _ := typ.(*Pointer); p != nil {
|
if p, _ := typ.(*Pointer); p != nil {
|
||||||
|
|
@ -301,6 +301,17 @@ func deref(typ Type) (Type, bool) {
|
||||||
return typ, false
|
return typ, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
|
||||||
|
// (named or unnamed) struct and returns its base. Otherwise it returns typ.
|
||||||
|
func derefStructPtr(typ Type) Type {
|
||||||
|
if p, _ := typ.Underlying().(*Pointer); p != nil {
|
||||||
|
if _, ok := p.base.Underlying().(*Struct); ok {
|
||||||
|
return p.base
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
|
||||||
// concat returns the result of concatenating list and i.
|
// concat returns the result of concatenating list and i.
|
||||||
// The result does not share its underlying array with list.
|
// The result does not share its underlying array with list.
|
||||||
func concat(list []int, i int) []int {
|
func concat(list []int, i int) []int {
|
||||||
|
|
|
||||||
|
|
@ -373,6 +373,10 @@ func _Offsetof() {
|
||||||
var y1p *S1
|
var y1p *S1
|
||||||
assert(unsafe.Offsetof(y1p.S0) == 32)
|
assert(unsafe.Offsetof(y1p.S0) == 32)
|
||||||
|
|
||||||
|
type P *S1
|
||||||
|
var p P = y1p
|
||||||
|
assert(unsafe.Offsetof(p.S0) == 32)
|
||||||
|
|
||||||
var y2 S2
|
var y2 S2
|
||||||
assert(unsafe.Offsetof(y2.S1) == 0)
|
assert(unsafe.Offsetof(y2.S1) == 0)
|
||||||
_ = unsafe.Offsetof(y2 /* ERROR "embedded via a pointer" */ .x)
|
_ = unsafe.Offsetof(y2 /* ERROR "embedded via a pointer" */ .x)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue