modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/inline_caller.go (about)

     1  // run -gcflags -l=4
     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  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  	"runtime"
    12  )
    13  
    14  type frame struct {
    15  	pc   uintptr
    16  	file string
    17  	line int
    18  	ok   bool
    19  }
    20  
    21  var (
    22  	skip        int
    23  	globalFrame frame
    24  )
    25  
    26  func f() {
    27  	g() // line 27
    28  }
    29  
    30  func g() {
    31  	h() // line 31
    32  }
    33  
    34  func h() {
    35  	x := &globalFrame
    36  	x.pc, x.file, x.line, x.ok = runtime.Caller(skip) // line 36
    37  }
    38  
    39  //go:noinline
    40  func testCaller(skp int) frame {
    41  	skip = skp
    42  	f() // line 42
    43  	frame := globalFrame
    44  	if !frame.ok {
    45  		panic(fmt.Sprintf("skip=%d runtime.Caller failed", skp))
    46  	}
    47  	return frame
    48  }
    49  
    50  type wantFrame struct {
    51  	funcName string
    52  	line     int
    53  }
    54  
    55  // -1 means don't care
    56  var expected = []wantFrame{
    57  	0: {"main.testCaller", 36},
    58  	1: {"main.testCaller", 31},
    59  	2: {"main.testCaller", 27},
    60  	3: {"main.testCaller", 42},
    61  	4: {"main.main", 68},
    62  	5: {"runtime.main", -1},
    63  	6: {"runtime.goexit", -1},
    64  }
    65  
    66  func main() {
    67  	for i := 0; i <= 6; i++ {
    68  		frame := testCaller(i) // line 68
    69  		fn := runtime.FuncForPC(frame.pc)
    70  		if expected[i].line >= 0 && frame.line != expected[i].line {
    71  			panic(fmt.Sprintf("skip=%d expected line %d, got line %d", i, expected[i].line, frame.line))
    72  		}
    73  		if fn.Name() != expected[i].funcName {
    74  			panic(fmt.Sprintf("skip=%d expected function %s, got %s", i, expected[i].funcName, fn.Name()))
    75  		}
    76  	}
    77  }