mirror of
https://github.com/golang/go
synced 2024-11-23 03:30:02 -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 {
|
||||
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() {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user