| // 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) |
| } |
| } |
| } |