1// run
2
3// Copyright 2017 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7package main
8
9import (
10	"log"
11	"reflect"
12	"runtime"
13)
14
15func hello() string {
16	return "Hello World" // line 16
17}
18
19func foo() string { // line 19
20	x := hello() // line 20
21	y := hello() // line 21
22	return x + y // line 22
23}
24
25func bar() string {
26	x := hello() // line 26
27	return x
28}
29
30// funcPC returns the PC for the func value f.
31func funcPC(f interface{}) uintptr {
32	return reflect.ValueOf(f).Pointer()
33}
34
35// Test for issue #15453. Previously, line 26 would appear in foo().
36func main() {
37	pc := funcPC(foo)
38	f := runtime.FuncForPC(pc)
39	for ; runtime.FuncForPC(pc) == f; pc++ {
40		file, line := f.FileLine(pc)
41		if line == 0 {
42			continue
43		}
44		// Line 16 can appear inside foo() because PC-line table has
45		// innermost line numbers after inlining.
46		if line != 16 && !(line >= 19 && line <= 22) {
47			log.Fatalf("unexpected line at PC=%d: %s:%d\n", pc, file, line)
48		}
49	}
50}
51