Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/goPublic

Commitb0454f5

Browse files
adgianlancetaylor
authored andcommitted
[release-branch.go1.3] cmd/cgo: fix recursive type mapping
««« CL 122850043 / 0015a2541545cmd/cgo: fix recursive type mappingInstead of immediately completing pointer type mappings, add them toa queue to allow them to be completed later. This fixes issuescausedby Type() returning arbitrary in-progress type mappings.Fixes#8368.Fixes#8441.LGTM=iantR=golang-codereviews, iantCC=golang-codereviewshttps://golang.org/cl/122850043»»»TBR=rscR=rscCC=golang-codereviewshttps://golang.org/cl/128940043
1 parentb48cd4b commitb0454f5

File tree

2 files changed

+71
-13
lines changed

2 files changed

+71
-13
lines changed

‎misc/cgo/test/issue8441.go‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2014 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+
// Issue 8368 and 8441. Recursive struct definitions didn't work.
6+
// No runtime test; just make sure it compiles.
7+
8+
package cgotest
9+
10+
/*
11+
typedef struct one one;
12+
typedef struct two two;
13+
struct one {
14+
two *x;
15+
};
16+
struct two {
17+
one *x;
18+
};
19+
*/
20+
import"C"
21+
22+
funcissue8368(one*C.struct_one,two*C.struct_two) {
23+
}
24+
25+
funcissue8441(one*C.one,two*C.two) {
26+
issue8441(two.x,one.x)
27+
}

‎src/cmd/cgo/gcc.go‎

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,8 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
552552
n.Const=fmt.Sprintf("%#x",enumVal[i])
553553
}
554554
}
555+
conv.FinishType(pos)
555556
}
556-
557557
}
558558

559559
// mangleName does name mangling to translate names
@@ -926,6 +926,12 @@ type typeConv struct {
926926
mmap[dwarf.Type]*Type
927927
typedefmap[string]ast.Expr
928928

929+
// Map from types to incomplete pointers to those types.
930+
ptrsmap[dwarf.Type][]*Type
931+
932+
// Fields to be processed by godefsField after completing pointers.
933+
todoFlds [][]*ast.Field
934+
929935
// Predeclared types.
930936
bool ast.Expr
931937
byte ast.Expr// denotes padding
@@ -950,6 +956,7 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
950956
c.ptrSize=ptrSize
951957
c.intSize=intSize
952958
c.m=make(map[dwarf.Type]*Type)
959+
c.ptrs=make(map[dwarf.Type][]*Type)
953960
c.bool=c.Ident("bool")
954961
c.byte=c.Ident("byte")
955962
c.int8=c.Ident("int8")
@@ -1029,6 +1036,32 @@ func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
10291036
tr.FormatArgs=fargs
10301037
}
10311038

1039+
// FinishType completes any outstanding type mapping work.
1040+
// In particular, it resolves incomplete pointer types and also runs
1041+
// godefsFields on any new struct types.
1042+
func (c*typeConv)FinishType(pos token.Pos) {
1043+
// Completing one pointer type might produce more to complete.
1044+
// Keep looping until they're all done.
1045+
forlen(c.ptrs)>0 {
1046+
fordtype:=rangec.ptrs {
1047+
// Note Type might invalidate c.ptrs[dtype].
1048+
t:=c.Type(dtype,pos)
1049+
for_,ptr:=rangec.ptrs[dtype] {
1050+
ptr.Go.(*ast.StarExpr).X=t.Go
1051+
ptr.C.Set("%s*",t.C)
1052+
}
1053+
delete(c.ptrs,dtype)
1054+
}
1055+
}
1056+
1057+
// Now that pointer types are completed, we can invoke godefsFields
1058+
// to rewrite struct definitions.
1059+
for_,fld:=rangec.todoFlds {
1060+
godefsFields(fld)
1061+
}
1062+
c.todoFlds=nil
1063+
}
1064+
10321065
// Type returns a *Type with the same memory layout as
10331066
// dtype when used as the type of a variable or a struct field.
10341067
func (c*typeConv)Type(dtype dwarf.Type,pos token.Pos)*Type {
@@ -1068,13 +1101,12 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
10681101
t.Go=c.Opaque(t.Size)
10691102
break
10701103
}
1071-
gt:=&ast.ArrayType{
1072-
Len:c.intExpr(dt.Count),
1073-
}
1074-
t.Go=gt// publish before recursive call
10751104
sub:=c.Type(dt.Type,pos)
10761105
t.Align=sub.Align
1077-
gt.Elt=sub.Go
1106+
t.Go=&ast.ArrayType{
1107+
Len:c.intExpr(dt.Count),
1108+
Elt:sub.Go,
1109+
}
10781110
t.C.Set("__typeof__(%s[%d])",sub.C,dt.Count)
10791111

10801112
case*dwarf.BoolType:
@@ -1184,11 +1216,10 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
11841216
break
11851217
}
11861218

1187-
gt:=&ast.StarExpr{}
1188-
t.Go=gt// publish before recursive call
1189-
sub:=c.Type(dt.Type,pos)
1190-
gt.X=sub.Go
1191-
t.C.Set("%s*",sub.C)
1219+
// Placeholder initialization; completed in FinishType.
1220+
t.Go=&ast.StarExpr{}
1221+
t.C.Set("<incomplete>*")
1222+
c.ptrs[dt.Type]=append(c.ptrs[dt.Type],t)
11921223

11931224
case*dwarf.QualType:
11941225
// Ignore qualifier.
@@ -1265,8 +1296,8 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
12651296
}
12661297
name:=c.Ident("_Ctype_"+dt.Name)
12671298
goIdent[name.Name]=name
1268-
t.Go=name// publish before recursive call
12691299
sub:=c.Type(dt.Type,pos)
1300+
t.Go=name
12701301
t.Size=sub.Size
12711302
t.Align=sub.Align
12721303
oldType:=typedef[name.Name]
@@ -1604,7 +1635,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
16041635
csyntax=buf.String()
16051636

16061637
if*godefs||*cdefs {
1607-
godefsFields(fld)
1638+
c.todoFlds=append(c.todoFlds,fld)
16081639
}
16091640
expr=&ast.StructType{Fields:&ast.FieldList{List:fld}}
16101641
return

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp