From 841d865a56dee8dc4c712eea8eacc3a3d5256c6e Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Wed, 20 Dec 2017 09:54:13 -0500 Subject: [PATCH] cmd/compile: second attempt at fix for issue 23179 My previous fix for issue 23179 was incomplete; it turns out that if an unnamed parameter is below a specific size threshold, it gets register-promoted away by the compiler (hence not encountered during some parts of DWARF inline info processing), but if it is sufficiently large, it is allocated to the stack as a named variable and treated as a regular parameter by DWARF generation. Interestingly, something in the ppc64le build of k8s causes an unnamed parameter to be retained (where on amd64 it is deleted), meaning that this wasn't caught in my amd64 testing. The fix is to insure that "_" params are treated in the same way that "~r%d" return temps are when matching up post-optimization inlined routine params with pre-inlining declarations. I've also updated the test case to include a "_" parameter with a very large size, which also triggers the bug on amd64. Fixes #23179. Change-Id: I961c84cc7a873ad3f8f91db098a5e13896c4856e Reviewed-on: https://go-review.googlesource.com/84975 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: David Chase Reviewed-by: Cherry Zhang Reviewed-by: Heschi Kreinick --- src/cmd/compile/internal/gc/dwinl.go | 9 +++------ test/fixedbugs/issue23179.dir/a.go | 6 +++++- test/fixedbugs/issue23179.dir/b.go | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/cmd/compile/internal/gc/dwinl.go b/src/cmd/compile/internal/gc/dwinl.go index 06eebc96e50..e4eae3e87f6 100644 --- a/src/cmd/compile/internal/gc/dwinl.go +++ b/src/cmd/compile/internal/gc/dwinl.go @@ -129,10 +129,10 @@ func assembleInlines(fnsym *obj.LSym, fn *Node, dwVars []*dwarf.Var) dwarf.InlCa DeclLine: sl[j].DeclLine, DeclCol: sl[j].DeclCol, } - returnTmp := strings.HasPrefix(sl[j].Name, "~r") + synthesized := strings.HasPrefix(sl[j].Name, "~r") || canonName == "_" if idx, found := m[vp]; found { sl[j].ChildIndex = int32(idx) - sl[j].IsInAbstract = !returnTmp + sl[j].IsInAbstract = !synthesized sl[j].Name = canonName } else { // Variable can't be found in the pre-inline dcl list. @@ -140,10 +140,7 @@ func assembleInlines(fnsym *obj.LSym, fn *Node, dwVars []*dwarf.Var) dwarf.InlCa // because a composite variable was split into pieces, // and we're looking at a piece. We can also see // return temps (~r%d) that were created during - // lowering. - if ii != 0 && !returnTmp { - Fatalf("unexpected: can't find var %s in preInliningDcls for %v\n", sl[j].Name, Ctxt.InlTree.InlinedFunction(int(ii-1))) - } + // lowering, or unnamed params ("_"). sl[j].ChildIndex = int32(synthCount) synthCount += 1 } diff --git a/test/fixedbugs/issue23179.dir/a.go b/test/fixedbugs/issue23179.dir/a.go index 1b796660fdc..3d2816fc69d 100644 --- a/test/fixedbugs/issue23179.dir/a.go +++ b/test/fixedbugs/issue23179.dir/a.go @@ -4,6 +4,10 @@ package a -func F(x int, _ int, _ bool) int { +type Large struct { + x [256]int +} + +func F(x int, _ int, _ bool, _ Large) int { return x } diff --git a/test/fixedbugs/issue23179.dir/b.go b/test/fixedbugs/issue23179.dir/b.go index edf5e6d8126..bec3d15e1e1 100644 --- a/test/fixedbugs/issue23179.dir/b.go +++ b/test/fixedbugs/issue23179.dir/b.go @@ -7,5 +7,5 @@ package b import "a" func G(x int) int { - return a.F(x, 1, false) + return a.F(x, 1, false, a.Large{}) }