mirror of
https://github.com/golang/go
synced 2024-11-18 02:54:47 -07:00
cmd/compile: check deferred nil interface call before wrapping it
Currently, for "defer i.M()" if i is nil it panics at the point of defer statement, not when deferred function is called. We need to do the nil check before wrapping it. Updates #40724. Change-Id: I62c669264668991f71999e2cf4610a9066247f9d Reviewed-on: https://go-review.googlesource.com/c/go/+/305549 Trust: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
4e1bf8ed38
commit
bd6628e62d
@ -1602,6 +1602,17 @@ func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
|
||||
n := callX.(*ir.SelectorExpr)
|
||||
n.X = mkArgCopy(n.X)
|
||||
methSelectorExpr = n
|
||||
if callX.Op() == ir.ODOTINTER {
|
||||
// Currently for "defer i.M()" if i is nil it panics at the
|
||||
// point of defer statement, not when deferred function is called.
|
||||
// (I think there is an issue discussing what is the intended
|
||||
// behavior but I cannot find it.)
|
||||
// We need to do the nil check outside of the wrapper.
|
||||
tab := typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X))
|
||||
c := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, tab)
|
||||
c.SetTypecheck(1)
|
||||
o.append(c)
|
||||
}
|
||||
case !(callX.Op() == ir.ONAME && callX.(*ir.Name).Class == ir.PFUNC):
|
||||
// Deal with "defer returnsafunc()(x, y)" (for
|
||||
// example) by copying the callee expression.
|
||||
|
Loading…
Reference in New Issue
Block a user