Commit 54cbc5b4 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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: default avatarKeith Randall <khr@golang.org>
parent f98081e5
...@@ -126,7 +126,12 @@ func TestReportsTypeErrors(t *testing.T) { ...@@ -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)
}
} }
} }
......
// 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) { ...@@ -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) { ...@@ -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) { ...@@ -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) ...@@ -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 { ...@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment