]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix bug in logic for computing var abstract origins
authorThan McIntosh <thanm@google.com>
Thu, 7 Dec 2017 01:10:51 +0000 (20:10 -0500)
committerThan McIntosh <thanm@google.com>
Thu, 7 Dec 2017 17:03:05 +0000 (17:03 +0000)
The DWARF inline info generation code was using file/line/column (from
src.Pos) as a means of matching up pre- and post-optimization variable
nodes. This turns out to be problematic since it looks as though
distinct formals on the same line can be assigned the same column
number. Work around this issue by adding variable names to the
disambiguation code. Added a testpoint to the linker DWARF test that
checks to make sure each abstract origin offset of distinct within a
given DWARF DW_AT_inlined_routine body.

Fixes #23020.

Change-Id: Ie09bbe01dc60822d84d4085547b138e644036fb3
Reviewed-on: https://go-review.googlesource.com/82396
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/gc/dwinl.go
src/cmd/link/internal/ld/dwarf_test.go

index f76bacc5b911d3596e999dbcd89652d1ebd3391e..dd91b6c0fc3b86d71a88dddb995e6ac4d46202f6 100644 (file)
@@ -14,6 +14,7 @@ import (
 
 // To identify variables by original source position.
 type varPos struct {
+       DeclName string
        DeclFile string
        DeclLine uint
        DeclCol  uint
@@ -96,14 +97,19 @@ func assembleInlines(fnsym *obj.LSym, fn *Node, dwVars []*dwarf.Var) dwarf.InlCa
                                n := dcl[i]
                                pos := Ctxt.InnermostPos(n.Pos)
                                vp := varPos{
+                                       DeclName: n.Sym.Name,
                                        DeclFile: pos.Base().SymFilename(),
                                        DeclLine: pos.Line(),
                                        DeclCol:  pos.Col(),
                                }
+                               if _, found := m[vp]; found {
+                                       Fatalf("child dcl collision on symbol %s within %v\n", n.Sym.Name, fnsym.Name)
+                               }
                                m[vp] = i
                        }
                        for j := 0; j < len(sl); j++ {
                                vp := varPos{
+                                       DeclName: sl[j].Name,
                                        DeclFile: sl[j].DeclFile,
                                        DeclLine: sl[j].DeclLine,
                                        DeclCol:  sl[j].DeclCol,
index 0bd5133f483d41b5385eb5018e07b33182e87930..4332a3dfba4dd8feb4e9d6e5300c74b314d7a6e6 100644 (file)
@@ -522,8 +522,13 @@ package main
 
 var G int
 
+func noinline(x int) int {
+       defer func() { G += x }()
+       return x
+}
+
 func cand(x, y int) int {
-    return (x + y) ^ (y - x)
+       return noinline(x+y) ^ (y - x)
 }
 
 func main() {
@@ -599,6 +604,24 @@ func main() {
                                }
                        }
                        exCount++
+
+                       omap := make(map[dwarf.Offset]bool)
+
+                       // Walk the child variables of the inlined routine. Each
+                       // of them should have a distinct abstract origin-- if two
+                       // vars point to the same origin things are definitely broken.
+                       inlIdx := ex.idxFromOffset(child.Offset)
+                       inlChildDies := ex.Children(inlIdx)
+                       for _, k := range inlChildDies {
+                               ooff, originOK := k.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
+                               if !originOK {
+                                       t.Fatalf("no abstract origin attr for child of inlined subroutine at offset %v", k.Offset)
+                               }
+                               if _, found := omap[ooff]; found {
+                                       t.Fatalf("duplicate abstract origin at child of inlined subroutine at offset %v", k.Offset)
+                               }
+                               omap[ooff] = true
+                       }
                }
        }
        if exCount != len(expectedInl) {