mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: use a plausible position for typedef error messages
Fixes #28069 Change-Id: I7e0f96b8b6d123de283325fcb78ec76455050f6d Reviewed-on: https://go-review.googlesource.com/c/152158 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
f98081e515
commit
54cbc5b4bf
4 changed files with 59 additions and 18 deletions
|
|
@ -126,7 +126,12 @@ func TestReportsTypeErrors(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if sizeofLongDouble(t) > 8 {
|
if sizeofLongDouble(t) > 8 {
|
||||||
check(t, "err4.go")
|
for _, file := range []string{
|
||||||
|
"err4.go",
|
||||||
|
"issue28069.go",
|
||||||
|
} {
|
||||||
|
check(t, file)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
26
misc/cgo/errors/src/issue28069.go
Normal file
26
misc/cgo/errors/src/issue28069.go
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Test that the error message for an unrepresentable typedef in a
|
||||||
|
// union appears on the right line. This test is only run if the size
|
||||||
|
// of long double is larger than 64.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef long double Float128;
|
||||||
|
|
||||||
|
typedef struct SV {
|
||||||
|
union {
|
||||||
|
Float128 float128;
|
||||||
|
} value;
|
||||||
|
} SV;
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
type ts struct {
|
||||||
|
tv *C.SV // ERROR HERE
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
|
@ -171,11 +171,13 @@ func (p *Package) Translate(f *File) {
|
||||||
for len(p.typedefs) > numTypedefs {
|
for len(p.typedefs) > numTypedefs {
|
||||||
numTypedefs = len(p.typedefs)
|
numTypedefs = len(p.typedefs)
|
||||||
// Also ask about any typedefs we've seen so far.
|
// Also ask about any typedefs we've seen so far.
|
||||||
for _, a := range p.typedefList {
|
for _, info := range p.typedefList {
|
||||||
f.Name[a] = &Name{
|
n := &Name{
|
||||||
Go: a,
|
Go: info.typedef,
|
||||||
C: a,
|
C: info.typedef,
|
||||||
}
|
}
|
||||||
|
f.Name[info.typedef] = n
|
||||||
|
f.NamePos[n] = info.pos
|
||||||
}
|
}
|
||||||
needType := p.guessKinds(f)
|
needType := p.guessKinds(f)
|
||||||
if len(needType) > 0 {
|
if len(needType) > 0 {
|
||||||
|
|
@ -573,7 +575,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
|
||||||
fatalf("malformed __cgo__ name: %s", name)
|
fatalf("malformed __cgo__ name: %s", name)
|
||||||
}
|
}
|
||||||
types[i] = t.Type
|
types[i] = t.Type
|
||||||
p.recordTypedefs(t.Type)
|
p.recordTypedefs(t.Type, f.NamePos[names[i]])
|
||||||
}
|
}
|
||||||
if e.Tag != dwarf.TagCompileUnit {
|
if e.Tag != dwarf.TagCompileUnit {
|
||||||
r.SkipChildren()
|
r.SkipChildren()
|
||||||
|
|
@ -641,10 +643,11 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
|
// recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
|
||||||
func (p *Package) recordTypedefs(dtype dwarf.Type) {
|
func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
|
||||||
p.recordTypedefs1(dtype, map[dwarf.Type]bool{})
|
p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
|
||||||
}
|
}
|
||||||
func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool) {
|
|
||||||
|
func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
|
||||||
if dtype == nil {
|
if dtype == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -660,23 +663,23 @@ func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool)
|
||||||
}
|
}
|
||||||
if !p.typedefs[dt.Name] {
|
if !p.typedefs[dt.Name] {
|
||||||
p.typedefs[dt.Name] = true
|
p.typedefs[dt.Name] = true
|
||||||
p.typedefList = append(p.typedefList, dt.Name)
|
p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
|
||||||
p.recordTypedefs1(dt.Type, visited)
|
p.recordTypedefs1(dt.Type, pos, visited)
|
||||||
}
|
}
|
||||||
case *dwarf.PtrType:
|
case *dwarf.PtrType:
|
||||||
p.recordTypedefs1(dt.Type, visited)
|
p.recordTypedefs1(dt.Type, pos, visited)
|
||||||
case *dwarf.ArrayType:
|
case *dwarf.ArrayType:
|
||||||
p.recordTypedefs1(dt.Type, visited)
|
p.recordTypedefs1(dt.Type, pos, visited)
|
||||||
case *dwarf.QualType:
|
case *dwarf.QualType:
|
||||||
p.recordTypedefs1(dt.Type, visited)
|
p.recordTypedefs1(dt.Type, pos, visited)
|
||||||
case *dwarf.FuncType:
|
case *dwarf.FuncType:
|
||||||
p.recordTypedefs1(dt.ReturnType, visited)
|
p.recordTypedefs1(dt.ReturnType, pos, visited)
|
||||||
for _, a := range dt.ParamType {
|
for _, a := range dt.ParamType {
|
||||||
p.recordTypedefs1(a, visited)
|
p.recordTypedefs1(a, pos, visited)
|
||||||
}
|
}
|
||||||
case *dwarf.StructType:
|
case *dwarf.StructType:
|
||||||
for _, f := range dt.Field {
|
for _, f := range dt.Field {
|
||||||
p.recordTypedefs1(f.Type, visited)
|
p.recordTypedefs1(f.Type, pos, visited)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,14 @@ type Package struct {
|
||||||
GccFiles []string // list of gcc output files
|
GccFiles []string // list of gcc output files
|
||||||
Preamble string // collected preamble for _cgo_export.h
|
Preamble string // collected preamble for _cgo_export.h
|
||||||
typedefs map[string]bool // type names that appear in the types of the objects we're interested in
|
typedefs map[string]bool // type names that appear in the types of the objects we're interested in
|
||||||
typedefList []string
|
typedefList []typedefInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// A typedefInfo is an element on Package.typedefList: a typedef name
|
||||||
|
// and the position where it was required.
|
||||||
|
type typedefInfo struct {
|
||||||
|
typedef string
|
||||||
|
pos token.Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
// A File collects information about a single Go input file.
|
// A File collects information about a single Go input file.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue