Skip to content

Commit 54cbc5b

Browse files
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent f98081e commit 54cbc5b

File tree

4 files changed

+59
-18
lines changed

4 files changed

+59
-18
lines changed

misc/cgo/errors/errors_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,12 @@ func TestReportsTypeErrors(t *testing.T) {
126126
}
127127

128128
if sizeofLongDouble(t) > 8 {
129-
check(t, "err4.go")
129+
for _, file := range []string{
130+
"err4.go",
131+
"issue28069.go",
132+
} {
133+
check(t, file)
134+
}
130135
}
131136
}
132137

misc/cgo/errors/src/issue28069.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Test that the error message for an unrepresentable typedef in a
6+
// union appears on the right line. This test is only run if the size
7+
// of long double is larger than 64.
8+
9+
package main
10+
11+
/*
12+
typedef long double Float128;
13+
14+
typedef struct SV {
15+
union {
16+
Float128 float128;
17+
} value;
18+
} SV;
19+
*/
20+
import "C"
21+
22+
type ts struct {
23+
tv *C.SV // ERROR HERE
24+
}
25+
26+
func main() {}

src/cmd/cgo/gcc.go

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,13 @@ func (p *Package) Translate(f *File) {
171171
for len(p.typedefs) > numTypedefs {
172172
numTypedefs = len(p.typedefs)
173173
// Also ask about any typedefs we've seen so far.
174-
for _, a := range p.typedefList {
175-
f.Name[a] = &Name{
176-
Go: a,
177-
C: a,
174+
for _, info := range p.typedefList {
175+
n := &Name{
176+
Go: info.typedef,
177+
C: info.typedef,
178178
}
179+
f.Name[info.typedef] = n
180+
f.NamePos[n] = info.pos
179181
}
180182
needType := p.guessKinds(f)
181183
if len(needType) > 0 {
@@ -573,7 +575,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
573575
fatalf("malformed __cgo__ name: %s", name)
574576
}
575577
types[i] = t.Type
576-
p.recordTypedefs(t.Type)
578+
p.recordTypedefs(t.Type, f.NamePos[names[i]])
577579
}
578580
if e.Tag != dwarf.TagCompileUnit {
579581
r.SkipChildren()
@@ -641,10 +643,11 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
641643
}
642644

643645
// recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
644-
func (p *Package) recordTypedefs(dtype dwarf.Type) {
645-
p.recordTypedefs1(dtype, map[dwarf.Type]bool{})
646+
func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
647+
p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
646648
}
647-
func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool) {
649+
650+
func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
648651
if dtype == nil {
649652
return
650653
}
@@ -660,23 +663,23 @@ func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool)
660663
}
661664
if !p.typedefs[dt.Name] {
662665
p.typedefs[dt.Name] = true
663-
p.typedefList = append(p.typedefList, dt.Name)
664-
p.recordTypedefs1(dt.Type, visited)
666+
p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
667+
p.recordTypedefs1(dt.Type, pos, visited)
665668
}
666669
case *dwarf.PtrType:
667-
p.recordTypedefs1(dt.Type, visited)
670+
p.recordTypedefs1(dt.Type, pos, visited)
668671
case *dwarf.ArrayType:
669-
p.recordTypedefs1(dt.Type, visited)
672+
p.recordTypedefs1(dt.Type, pos, visited)
670673
case *dwarf.QualType:
671-
p.recordTypedefs1(dt.Type, visited)
674+
p.recordTypedefs1(dt.Type, pos, visited)
672675
case *dwarf.FuncType:
673-
p.recordTypedefs1(dt.ReturnType, visited)
676+
p.recordTypedefs1(dt.ReturnType, pos, visited)
674677
for _, a := range dt.ParamType {
675-
p.recordTypedefs1(a, visited)
678+
p.recordTypedefs1(a, pos, visited)
676679
}
677680
case *dwarf.StructType:
678681
for _, f := range dt.Field {
679-
p.recordTypedefs1(f.Type, visited)
682+
p.recordTypedefs1(f.Type, pos, visited)
680683
}
681684
}
682685
}

src/cmd/cgo/main.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,14 @@ type Package struct {
4747
GccFiles []string // list of gcc output files
4848
Preamble string // collected preamble for _cgo_export.h
4949
typedefs map[string]bool // type names that appear in the types of the objects we're interested in
50-
typedefList []string
50+
typedefList []typedefInfo
51+
}
52+
53+
// A typedefInfo is an element on Package.typedefList: a typedef name
54+
// and the position where it was required.
55+
type typedefInfo struct {
56+
typedef string
57+
pos token.Pos
5158
}
5259

5360
// A File collects information about a single Go input file.

0 commit comments

Comments
 (0)