]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: nilcheck interface value in go/defer interface call for SSA
authorCherry Zhang <cherryyz@google.com>
Mon, 6 Jun 2016 20:00:33 +0000 (16:00 -0400)
committerCherry Zhang <cherryyz@google.com>
Wed, 8 Jun 2016 20:35:53 +0000 (20:35 +0000)
This matches the behavior of the legacy backend.

Fixes #15975 (if this is the intended behavior)

Change-Id: Id277959069b8b8bf9958fa8f2cbc762c752a1a19
Reviewed-on: https://go-review.googlesource.com/23820
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/ssa.go
test/fixedbugs/issue15975.go [new file with mode: 0644]

index d27ac4392f78f754239e9f0f2116b063fc846272..c0e6045216220bd48ffbb9025e4bd252d48bc003 100644 (file)
@@ -2573,6 +2573,9 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
                }
                i := s.expr(fn.Left)
                itab := s.newValue1(ssa.OpITab, Types[TUINTPTR], i)
+               if k != callNormal {
+                       s.nilCheck(itab)
+               }
                itabidx := fn.Xoffset + 3*int64(Widthptr) + 8 // offset of fun field in runtime.itab
                itab = s.newValue1I(ssa.OpOffPtr, Types[TUINTPTR], itabidx, itab)
                if k == callNormal {
diff --git a/test/fixedbugs/issue15975.go b/test/fixedbugs/issue15975.go
new file mode 100644 (file)
index 0000000..56a50e1
--- /dev/null
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var fail bool
+
+type Closer interface {
+       Close()
+}
+
+func nilInterfaceDeferCall() {
+       var x Closer
+       defer x.Close()
+       // if it panics when evaluating x.Close, it should not reach here
+       fail = true
+}
+
+func shouldPanic(f func()) {
+       defer func() {
+               if recover() == nil {
+                       panic("did not panic")
+               }
+       }()
+       f()
+}
+
+func main() {
+       shouldPanic(nilInterfaceDeferCall)
+       if fail {
+               panic("fail")
+       }
+}