mirror of https://github.com/golang/go.git
cmd/compile: try to preserve IsStmt marks from OpConvert
Note when a statement mark was not consumed during Prog generation, and try to use it on a subsequent opcode so that the statement marker will not be lost. And a test. Fixes #49628. Change-Id: I03f7782a9809cc4a0a5870df92b3e182cf124554 Reviewed-on: https://go-review.googlesource.com/c/go/+/366694 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> Trust: Dan Scales <danscales@google.com> Reviewed-by: Dan Scales <danscales@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
7b7efd7a7c
commit
61011de1af
|
|
@ -82,6 +82,25 @@ func TestDebugLinesPushback(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDebugLinesConvert(t *testing.T) {
|
||||||
|
if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { // in particular, it could be windows.
|
||||||
|
t.Skip("this test depends on creating a file with a wonky name, only works for sure on Linux and Darwin")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch testGoArch() {
|
||||||
|
default:
|
||||||
|
t.Skip("skipped for many architectures")
|
||||||
|
|
||||||
|
case "arm64", "amd64": // register ABI
|
||||||
|
fn := "G[go.shape.int_0]"
|
||||||
|
if buildcfg.Experiment.Unified {
|
||||||
|
// Unified mangles differently
|
||||||
|
fn = "G[int]"
|
||||||
|
}
|
||||||
|
testDebugLines(t, "-N -l -G=3", "convertline.go", fn, []int{9, 10, 11}, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestInlineLines(t *testing.T) {
|
func TestInlineLines(t *testing.T) {
|
||||||
if runtime.GOARCH != "amd64" && *testGoArchFlag == "" {
|
if runtime.GOARCH != "amd64" && *testGoArchFlag == "" {
|
||||||
// As of september 2021, works for everything except mips64, but still potentially fragile
|
// As of september 2021, works for everything except mips64, but still potentially fragile
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func F[T any](n T) {
|
||||||
|
fmt.Printf("called\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func G[T any](n T) {
|
||||||
|
F(n)
|
||||||
|
fmt.Printf("after\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
G(3)
|
||||||
|
}
|
||||||
|
|
@ -6577,6 +6577,22 @@ func (s *State) DebugFriendlySetPosFrom(v *ssa.Value) {
|
||||||
// explicit statement boundaries should appear
|
// explicit statement boundaries should appear
|
||||||
// in the generated code.
|
// in the generated code.
|
||||||
if p.IsStmt() != src.PosIsStmt {
|
if p.IsStmt() != src.PosIsStmt {
|
||||||
|
if s.pp.Pos.IsStmt() == src.PosIsStmt && s.pp.Pos.SameFileAndLine(p) {
|
||||||
|
// If s.pp.Pos already has a statement mark, then it was set here (below) for
|
||||||
|
// the previous value. If an actual instruction had been emitted for that
|
||||||
|
// value, then the statement mark would have been reset. Since the statement
|
||||||
|
// mark of s.pp.Pos was not reset, this position (file/line) still needs a
|
||||||
|
// statement mark on an instruction. If file and line for this value are
|
||||||
|
// the same as the previous value, then the first instruction for this
|
||||||
|
// value will work to take the statement mark. Return early to avoid
|
||||||
|
// resetting the statement mark.
|
||||||
|
//
|
||||||
|
// The reset of s.pp.Pos occurs in (*Progs).Prog() -- if it emits
|
||||||
|
// an instruction, and the instruction's statement mark was set,
|
||||||
|
// and it is not one of the LosesStmtMark instructions,
|
||||||
|
// then Prog() resets the statement mark on the (*Progs).Pos.
|
||||||
|
return
|
||||||
|
}
|
||||||
p = p.WithNotStmt()
|
p = p.WithNotStmt()
|
||||||
// Calls use the pos attached to v, but copy the statement mark from State
|
// Calls use the pos attached to v, but copy the statement mark from State
|
||||||
}
|
}
|
||||||
|
|
@ -6818,6 +6834,7 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
|
||||||
for i, b := range f.Blocks {
|
for i, b := range f.Blocks {
|
||||||
s.bstart[b.ID] = s.pp.Next
|
s.bstart[b.ID] = s.pp.Next
|
||||||
s.lineRunStart = nil
|
s.lineRunStart = nil
|
||||||
|
s.SetPos(s.pp.Pos.WithNotStmt()) // It needs a non-empty Pos, but cannot be a statement boundary (yet).
|
||||||
|
|
||||||
// Attach a "default" liveness info. Normally this will be
|
// Attach a "default" liveness info. Normally this will be
|
||||||
// overwritten in the Values loop below for each Value. But
|
// overwritten in the Values loop below for each Value. But
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue