| Server IP : 216.92.14.13 / Your IP : 216.73.216.171 Web Server : Apache System : Linux vps4089.pairvps.com 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 User : rmlac2fmr ( 1040637) PHP Version : 8.2.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/local/go/test/ |
Upload File : |
// run
// Copyright 2025 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
import (
"fmt"
"runtime"
"strings"
)
type A interface{ A() }
type Impl struct{}
func (*Impl) A() {}
type Impl2 struct{}
func (*Impl2) A() {}
func main() {
shouldNilPanic(28, func() {
var v A
v.A()
v = &Impl{}
})
shouldNilPanic(36, func() {
var v A
defer func() {
v = &Impl{}
}()
v.A()
})
shouldNilPanic(43, func() {
var v A
f := func() {
v = &Impl{}
}
v.A()
f()
})
// Make sure that both devirtualized and non devirtualized
// variants have the panic at the same line.
shouldNilPanic(55, func() {
var v A
defer func() {
v = &Impl{}
}()
v. // A() is on a sepearate line
A()
})
shouldNilPanic(64, func() {
var v A
defer func() {
v = &Impl{}
v = &Impl2{} // assign different type, such that the call below does not get devirtualized
}()
v. // A() is on a sepearate line
A()
})
}
var cnt = 0
func shouldNilPanic(wantLine int, f func()) {
cnt++
defer func() {
p := recover()
if p == nil {
panic("no nil deref panic")
}
if strings.Contains(fmt.Sprintf("%s", p), "invalid memory address or nil pointer dereference") {
callers := make([]uintptr, 128)
n := runtime.Callers(0, callers)
callers = callers[:n]
frames := runtime.CallersFrames(callers)
line := -1
for f, next := frames.Next(); next; f, next = frames.Next() {
if f.Func.Name() == fmt.Sprintf("main.main.func%v", cnt) {
line = f.Line
break
}
}
if line != wantLine {
panic(fmt.Sprintf("invalid line number in panic = %v; want = %v", line, wantLine))
}
return
}
panic(p)
}()
f()
}