aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlessandro Arzilli <alessandro.arzilli@gmail.com>2022-09-23 17:31:19 +0200
committerThan McIntosh <thanm@google.com>2022-10-28 17:49:22 +0000
commite59d873ff906550ace73b86bdb74b68ebe482a10 (patch)
tree3e3f28b67d2dacf3b5675857e7235519dba89ac4 /src
parent77296e36457b070bc811a605c4c4bd6c36d972ae (diff)
downloadgo-e59d873ff906550ace73b86bdb74b68ebe482a10.tar.xz
cmd/compile: emit DIEs for zero sized variables
Fixes the compiler to emit DIEs for zero sized variables. Fixes #54615 Change-Id: I1e0c86a97f1abcc7edae516b6a7fe35bcb65ed0f Reviewed-on: https://go-review.googlesource.com/c/go/+/433479 Reviewed-by: Damien Neil <dneil@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Alessandro Arzilli <alessandro.arzilli@gmail.com> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/dwarfgen/dwarf.go15
-rw-r--r--src/cmd/compile/internal/ssa/debug.go2
-rw-r--r--src/cmd/compile/internal/ssagen/pgen.go1
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go53
4 files changed, 71 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/dwarfgen/dwarf.go b/src/cmd/compile/internal/dwarfgen/dwarf.go
index 179152f5bf..90c331f0b6 100644
--- a/src/cmd/compile/internal/dwarfgen/dwarf.go
+++ b/src/cmd/compile/internal/dwarfgen/dwarf.go
@@ -151,6 +151,21 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
} else {
decls, vars, selected = createSimpleVars(fnsym, apDecls)
}
+ if fn.DebugInfo != nil {
+ // Recover zero sized variables eliminated by the stackframe pass
+ for _, n := range fn.DebugInfo.(*ssa.FuncDebug).OptDcl {
+ if n.Class != ir.PAUTO {
+ continue
+ }
+ types.CalcSize(n.Type())
+ if n.Type().Size() == 0 {
+ decls = append(decls, n)
+ vars = append(vars, createSimpleVar(fnsym, n))
+ vars[len(vars)-1].StackOffset = 0
+ fnsym.Func().RecordAutoType(reflectdata.TypeLinksym(n.Type()))
+ }
+ }
+ }
dcl := apDecls
if fnsym.WasInlined() {
diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go
index 3eaba3a238..584aaef3bf 100644
--- a/src/cmd/compile/internal/ssa/debug.go
+++ b/src/cmd/compile/internal/ssa/debug.go
@@ -38,6 +38,8 @@ type FuncDebug struct {
// Register-resident output parameters for the function. This is filled in at
// SSA generation time.
RegOutputParams []*ir.Name
+ // Variable declarations that were removed during optimization
+ OptDcl []*ir.Name
// Filled in by the user. Translates Block and Value ID to PC.
GetPC func(ID, ID) int64
diff --git a/src/cmd/compile/internal/ssagen/pgen.go b/src/cmd/compile/internal/ssagen/pgen.go
index 7e7c13adc9..6b29e83697 100644
--- a/src/cmd/compile/internal/ssagen/pgen.go
+++ b/src/cmd/compile/internal/ssagen/pgen.go
@@ -140,6 +140,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
continue
}
if !n.Used() {
+ fn.DebugInfo.(*ssa.FuncDebug).OptDcl = fn.Dcl[i:]
fn.Dcl = fn.Dcl[:i]
break
}
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index 65f82d9d78..3132e1233c 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -1917,3 +1917,56 @@ func main() {
t.Errorf("no LPT entries for test.go")
}
}
+
+func TestZeroSizedVariable(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+
+ if runtime.GOOS == "plan9" {
+ t.Skip("skipping on plan9; no DWARF symbol table in executables")
+ }
+ t.Parallel()
+
+ // This test verifies that the compiler emits DIEs for zero sized variables
+ // (for example variables of type 'struct {}').
+ // See go.dev/issues/54615.
+
+ const prog = `
+package main
+
+import (
+ "fmt"
+)
+
+func main() {
+ zeroSizedVariable := struct{}{}
+ fmt.Println(zeroSizedVariable)
+}
+`
+
+ for _, opt := range []string{NoOpt, DefaultOpt} {
+ dir := t.TempDir()
+ f := gobuild(t, dir, prog, opt)
+ defer f.Close()
+ defer os.RemoveAll(dir)
+
+ d, err := f.DWARF()
+ if err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+
+ rdr := d.Reader()
+ ex := dwtest.Examiner{}
+ if err := ex.Populate(rdr); err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+
+ // Locate the main.zeroSizedVariable DIE
+ abcs := ex.Named("zeroSizedVariable")
+ if len(abcs) == 0 {
+ t.Fatalf("unable to locate DIE for zeroSizedVariable")
+ }
+ if len(abcs) != 1 {
+ t.Fatalf("more than one zeroSizedVariable DIE")
+ }
+ }
+}