mirror of
https://github.com/golang/go
synced 2024-11-12 02:00:23 -07:00
cmd/compile/internal/types2: simplify under() and fix a crash
The simplified version of under exposed a bug (by crashing): When a pointer base is used before the pointer is fully set up, the base is nil. Set the pointer base to Typ[Invalid] when creating the pointer, and add an extra safety check into deref. Reviewed all code that creates pointers. The same error cannot happen with other types because accessing parts of another type results in an expression that is not a type, and thus these kids of cycles cannot happen. Change-Id: I8332a281a534c094cfbb3623a636960865813ff6 Reviewed-on: https://go-review.googlesource.com/c/go/+/363665 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
c54605266b
commit
c2397905e0
@ -491,6 +491,13 @@ func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Fun
|
||||
// Otherwise it returns (typ, false).
|
||||
func deref(typ Type) (Type, bool) {
|
||||
if p, _ := typ.(*Pointer); p != nil {
|
||||
// p.base should never be nil, but be conservative
|
||||
if p.base == nil {
|
||||
if debug {
|
||||
panic("pointer with nil base type (possibly due to an invalid cyclic declaration)")
|
||||
}
|
||||
return Typ[Invalid], true
|
||||
}
|
||||
return p.base, true
|
||||
}
|
||||
return typ, false
|
||||
|
@ -45,6 +45,7 @@ type (
|
||||
|
||||
// pointers
|
||||
P0 *P0
|
||||
PP *struct{ PP.f /* ERROR no field or method f */ }
|
||||
|
||||
// functions
|
||||
F0 func(F0)
|
||||
|
@ -21,13 +21,10 @@ type Type interface {
|
||||
// under must only be called when a type is known
|
||||
// to be fully set up.
|
||||
func under(t Type) Type {
|
||||
switch t := t.(type) {
|
||||
case *Named:
|
||||
if t, _ := t.(*Named); t != nil {
|
||||
return t.under()
|
||||
case *TypeParam:
|
||||
return t.iface()
|
||||
}
|
||||
return t
|
||||
return t.Underlying()
|
||||
}
|
||||
|
||||
// If x and y are identical, match returns x.
|
||||
|
@ -315,6 +315,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
|
||||
case *syntax.Operation:
|
||||
if e.Op == syntax.Mul && e.Y == nil {
|
||||
typ := new(Pointer)
|
||||
typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
|
||||
def.setUnderlying(typ)
|
||||
typ.base = check.varType(e.X)
|
||||
// If typ.base is invalid, it's unlikely that *base is particularly
|
||||
|
Loading…
Reference in New Issue
Block a user