]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix regression in DWARF inlined routine variable tracking
authorThan McIntosh <thanm@google.com>
Tue, 20 Mar 2018 16:36:37 +0000 (12:36 -0400)
committerThan McIntosh <thanm@google.com>
Tue, 20 Mar 2018 18:56:52 +0000 (18:56 +0000)
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>
src/cmd/compile/internal/gc/dwinl.go
src/cmd/link/internal/ld/dwarf_test.go

index 29782b268369feeec5b2f207dc6054d47b743e9a..33c8c8b058aa7fc75783e21f9317c7d5d2056ef1 100644 (file)
@@ -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 {
index 54e692865a2bac1e194eb523906f26e5a6fe4f6a..a3790e4a2717ec642d41de7f1726675228bd334f 100644 (file)
@@ -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")
                        }