| // run | |
| // Copyright 2017 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 ( | |
| "log" | |
| "reflect" | |
| "runtime" | |
| ) | |
| func hello() string { | |
| return "Hello World" // line 16 | |
| } | |
| func foo() string { // line 19 | |
| x := hello() // line 20 | |
| y := hello() // line 21 | |
| return x + y // line 22 | |
| } | |
| func bar() string { | |
| x := hello() // line 26 | |
| return x | |
| } | |
| // funcPC returns the PC for the func value f. | |
| func funcPC(f interface{}) uintptr { | |
| return reflect.ValueOf(f).Pointer() | |
| } | |
| // Test for issue #15453. Previously, line 26 would appear in foo(). | |
| func main() { | |
| pc := funcPC(foo) | |
| f := runtime.FuncForPC(pc) | |
| for ; runtime.FuncForPC(pc) == f; pc++ { | |
| file, line := f.FileLine(pc) | |
| if line == 0 { | |
| continue | |
| } | |
| // Line 16 can appear inside foo() because PC-line table has | |
| // innermost line numbers after inlining. | |
| if line != 16 && !(line >= 19 && line <= 22) { | |
| log.Fatalf("unexpected line at PC=%d: %s:%d\n", pc, file, line) | |
| } | |
| } | |
| } |