diff --git a/cl/compile_test.go b/cl/compile_test.go index 108cbb7353..6abbb6c1e2 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -206,6 +206,15 @@ func TestRunAndTestFromTestlto(t *testing.T) { cltest.RunAndTestFromDir(t, "", "./_testlto", ignore, cltest.WithRunConfig(conf)) } +func TestRunAndTestFromTestltoDWARF(t *testing.T) { + t.Setenv("LLGO_BUILD_CACHE", "off") + conf := build.NewDefaultConf(build.ModeRun) + conf.LTO = lto.Full + conf.LinkOptions.DWARF = build.DWARFPreserve + cltest.RunAndTestFromDir(t, "reflectmk_runtime", "./_testlto", nil, + cltest.WithRunConfig(conf), cltest.WithIRCheck(false)) +} + var testltoSymbolChecks = []string{ "globaldce_interface_matrix", "globaldce_interface_slots", @@ -260,6 +269,14 @@ func TestRunAndTestFromTestltoLTOPlugin(t *testing.T) { ) } +func TestRunAndTestFromTestltoLTOPluginDWARF(t *testing.T) { + t.Setenv("LLGO_BUILD_CACHE", "off") + conf := testltoLTOPluginConf(t, build.ModeRun) + conf.LinkOptions.DWARF = build.DWARFPreserve + cltest.RunAndTestFromDir(t, "ltoplugin_switch", "./_testlto", nil, + cltest.WithRunConfig(conf), cltest.WithIRCheck(false)) +} + func TestBuildAndCheckSymbolsFromTestltoLTOPlugin(t *testing.T) { buildConf := testltoLTOPluginConf(t, build.ModeBuild) cltest.BuildAndCheckSymbolsFromDir(t, "", "./_testlto", testltoLTOPluginTests, diff --git a/ssa/di_debug_test.go b/ssa/di_debug_test.go index aebb9d016f..8b81848c01 100644 --- a/ssa/di_debug_test.go +++ b/ssa/di_debug_test.go @@ -166,6 +166,48 @@ type Shape struct { } } +func TestDeferInitBuilderInheritsDebugLocation(t *testing.T) { + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, "defer.go", `package p +func f() {} +`, 0) + if err != nil { + t.Fatal(err) + } + typesPkg, err := (&types.Config{}).Check("example.com/p", fset, []*ast.File{file}, nil) + if err != nil { + t.Fatal(err) + } + + prog := NewProgram(&Target{OptLevel: optlevel.O0}) + defer prog.Dispose() + prog.TypeSizes(types.SizesFor("gc", runtime.GOARCH)) + pkg := prog.NewPackage("p", "example.com/p") + pkg.InitDebug("p", "example.com/p", fset) + decl := file.Decls[0].(*ast.FuncDecl) + object := typesPkg.Scope().Lookup("f").(*types.Func) + fn := pkg.NewFunc("example.com/p.f", object.Type().(*types.Signature), InGo) + builder := fn.MakeBody(1) + defer builder.Dispose() + bodyPos := fset.Position(decl.Body.Lbrace) + builder.DebugFunction(fn, object.Scope(), fset.Position(object.Pos()), bodyPos) + builder.DISetCurrentDebugLocation(fn, bodyPos) + builder.Return() + + deferBuilder, next := fn.deferInitBuilder(builder) + defer deferBuilder.Dispose() + loc := deferBuilder.impl.GetCurrentDebugLocation() + if loc.Line != uint(bodyPos.Line) || loc.Col != uint(bodyPos.Column) || loc.Scope != fn.diFunc.ll { + t.Fatalf("defer debug location = %+v, want %s:%d:%d", loc, bodyPos.Filename, bodyPos.Line, bodyPos.Column) + } + deferBuilder.Jump(next) + + pkg.FinalizeDebug() + if err := llvm.VerifyModule(pkg.Module(), llvm.ReturnStatusAction); err != nil { + t.Fatalf("defer debug metadata is invalid: %v\n%s", err, pkg.Module().String()) + } +} + func newDebugRuntimePackage() *types.Package { pkg := types.NewPackage(PkgRuntime, "runtime") unsafePointer := types.Typ[types.UnsafePointer] diff --git a/ssa/eh.go b/ssa/eh.go index b8ead4eb64..e18149ebc3 100644 --- a/ssa/eh.go +++ b/ssa/eh.go @@ -136,8 +136,14 @@ func (b Builder) Longjmp(jb, retval Expr) { // ----------------------------------------------------------------------------- -func (p Function) deferInitBuilder() (b Builder, next BasicBlock) { +func (p Function) deferInitBuilder(from Builder) (b Builder, next BasicBlock) { b = p.NewBuilder() + if p.diFunc != nil { + loc := from.impl.GetCurrentDebugLocation() + if !loc.Scope.IsNil() { + b.impl.SetCurrentDebugLocation(loc.Line, loc.Col, loc.Scope, loc.InlinedAt) + } + } next = b.setBlockMoveLast(p.blks[0]) p.blks[0].last = next.last return @@ -197,7 +203,7 @@ func (b Builder) getDefer(kind DoAction) *aDefer { // TODO(xsw): check if in pkg.init var next, panicBlk BasicBlock if kind != DeferAlways { - b, next = self.deferInitBuilder() + b, next = self.deferInitBuilder(b) } blks := self.MakeBlocks(2)