mirror of
https://github.com/golang/go
synced 2024-11-26 19:51:17 -07:00
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>
This commit is contained in:
parent
77296e3645
commit
e59d873ff9
@ -151,6 +151,21 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
|
|||||||
} else {
|
} else {
|
||||||
decls, vars, selected = createSimpleVars(fnsym, apDecls)
|
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
|
dcl := apDecls
|
||||||
if fnsym.WasInlined() {
|
if fnsym.WasInlined() {
|
||||||
|
@ -38,6 +38,8 @@ type FuncDebug struct {
|
|||||||
// Register-resident output parameters for the function. This is filled in at
|
// Register-resident output parameters for the function. This is filled in at
|
||||||
// SSA generation time.
|
// SSA generation time.
|
||||||
RegOutputParams []*ir.Name
|
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.
|
// Filled in by the user. Translates Block and Value ID to PC.
|
||||||
GetPC func(ID, ID) int64
|
GetPC func(ID, ID) int64
|
||||||
|
@ -140,6 +140,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !n.Used() {
|
if !n.Used() {
|
||||||
|
fn.DebugInfo.(*ssa.FuncDebug).OptDcl = fn.Dcl[i:]
|
||||||
fn.Dcl = fn.Dcl[:i]
|
fn.Dcl = fn.Dcl[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1917,3 +1917,56 @@ func main() {
|
|||||||
t.Errorf("no LPT entries for test.go")
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user