aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2018-03-20 12:36:37 -0400
committerThan McIntosh <thanm@google.com>2018-03-20 18:56:52 +0000
commitf45c07e84ad17dcc4d927fb6571f81fc9fd99cdf (patch)
tree25aaad52f2497315571f4686568bc42084f76289
parentae10914e67e6e99fec94b3d190558131a24ecd8e (diff)
downloadgo-f45c07e84ad17dcc4d927fb6571f81fc9fd99cdf.tar.xz
cmd/compile: fix regression in DWARF inlined routine variable tracking
Fix a bug in the code that generates the pre-inlined variable declaration table used as raw material for emitting DWARF inline routine records. The fix for issue 23704 altered the recipe for assigning file/line/col to variables in one part of the compiler, but didn't update a similar recipe in the code for variable tracking. Added a new test that should catch problems of a similar nature. Fixes #24460. Change-Id: I255c036637f4151aa579c0e21d123fd413724d61 Reviewed-on: https://go-review.googlesource.com/101676 Reviewed-by: Alessandro Arzilli <alessandro.arzilli@gmail.com> Reviewed-by: Heschi Kreinick <heschi@google.com>
-rw-r--r--src/cmd/compile/internal/gc/dwinl.go8
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go21
2 files changed, 26 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/gc/dwinl.go b/src/cmd/compile/internal/gc/dwinl.go
index 29782b2683..33c8c8b058 100644
--- a/src/cmd/compile/internal/gc/dwinl.go
+++ b/src/cmd/compile/internal/gc/dwinl.go
@@ -209,7 +209,9 @@ func unversion(name string) string {
// Given a function that was inlined as part of the compilation, dig
// up the pre-inlining DCL list for the function and create a map that
// supports lookup of pre-inline dcl index, based on variable
-// position/name.
+// position/name. NB: the recipe for computing variable pos/file/line
+// needs to be kept in sync with the similar code in gc.createSimpleVars
+// and related functions.
func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
dcl := preInliningDcls(fnsym)
m := make(map[varPos]int)
@@ -218,8 +220,8 @@ func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
pos := Ctxt.InnermostPos(n.Pos)
vp := varPos{
DeclName: unversion(n.Sym.Name),
- DeclFile: pos.Base().SymFilename(),
- DeclLine: pos.Line(),
+ DeclFile: pos.RelFilename(),
+ DeclLine: pos.RelLine(),
DeclCol: pos.Col(),
}
if _, found := m[vp]; found {
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index 54e692865a..a3790e4a27 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -620,6 +620,27 @@ func main() {
t.Fatalf("can't locate origin DIE at off %v", ooff)
}
+ // Walk the children of the abstract subroutine. We expect
+ // to see child variables there, even if (perhaps due to
+ // optimization) there are no references to them from the
+ // inlined subroutine DIE.
+ absFcnIdx := ex.idxFromOffset(ooff)
+ absFcnChildDies := ex.Children(absFcnIdx)
+ if len(absFcnChildDies) != 2 {
+ t.Fatalf("expected abstract function: expected 2 children, got %d children", len(absFcnChildDies))
+ }
+ formalCount := 0
+ for _, absChild := range absFcnChildDies {
+ if absChild.Tag == dwarf.TagFormalParameter {
+ formalCount += 1
+ continue
+ }
+ t.Fatalf("abstract function child DIE: expected formal, got %v", absChild.Tag)
+ }
+ if formalCount != 2 {
+ t.Fatalf("abstract function DIE: expected 2 formals, got %d", formalCount)
+ }
+
if exCount >= len(expectedInl) {
t.Fatalf("too many inlined subroutines found in main.main")
}