Commit 4d38d126 authored by Shenghou Ma's avatar Shenghou Ma

cmd/cgo: simpler fix for issue 6506.

Replaces CL 14682044.
Fixes #6506.

R=rsc, iant, dave
CC=golang-dev
https://golang.org/cl/14717043
parent 244014e4
...@@ -543,7 +543,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) { ...@@ -543,7 +543,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
f, fok := types[i].(*dwarf.FuncType) f, fok := types[i].(*dwarf.FuncType)
if n.Kind != "type" && fok { if n.Kind != "type" && fok {
n.Kind = "func" n.Kind = "func"
n.FuncType = conv.FuncType(n, f, pos) n.FuncType = conv.FuncType(f, pos)
} else { } else {
n.Type = conv.Type(types[i], pos) n.Type = conv.Type(types[i], pos)
if enums[i] != 0 && n.Type.EnumValues != nil { if enums[i] != 0 && n.Type.EnumValues != nil {
...@@ -757,6 +757,13 @@ func (p *Package) gccCmd() []string { ...@@ -757,6 +757,13 @@ func (p *Package) gccCmd() []string {
"-Wno-unneeded-internal-declaration", "-Wno-unneeded-internal-declaration",
"-Wno-unused-function", "-Wno-unused-function",
"-Qunused-arguments", "-Qunused-arguments",
// Clang embeds prototypes for some builtin functions,
// like malloc and calloc, but all size_t parameters are
// incorrectly typed unsigned long. We work around that
// by disabling the builtin functions (this is safe as
// it won't affect the actual compilation of the C code).
// See: http://golang.org/issue/6506.
"-fno-builtin",
) )
} }
...@@ -1327,41 +1334,6 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { ...@@ -1327,41 +1334,6 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
return t return t
} }
// Clang contains built-in prototypes for many functions in the standard library.
// If you use the function without a header, clang uses these definitions to print
// an error telling which header to #include and then to continue on with the correct
// prototype. Unfortunately, the DWARF debug information generated for one
// of these functions, even after the header has been #included, records each of
// the size_t arguments as an unsigned long instead. Go treats C.ulong and C.size_t
// as different types, so we must correct the prototype for code that works on other
// systems to work with clang and vice versa. See golang.org/issue/6506#c21.
var usesSizeT = map[string]bool{
"alloca": true,
"bzero": true,
"calloc": true,
"malloc": true,
"memchr": true,
"memcmp": true,
"memcpy": true,
"memmove": true,
"memset": true,
"realloc": true,
"snprintf": true,
"stpncpy": true,
"strcspn": true,
"strlcat": true,
"strlcpy": true,
"strlen": true,
"strncasecmp": true,
"strncat": true,
"strncmp": true,
"strncpy": true,
"strndup": true,
"strspn": true,
"strxfrm": true,
"vsnprintf": true,
}
// FuncArg returns a Go type with the same memory layout as // FuncArg returns a Go type with the same memory layout as
// dtype when used as the type of a C function argument. // dtype when used as the type of a C function argument.
func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
...@@ -1378,7 +1350,6 @@ func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { ...@@ -1378,7 +1350,6 @@ func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
Go: &ast.StarExpr{X: t.Go}, Go: &ast.StarExpr{X: t.Go},
C: tr, C: tr,
} }
case *dwarf.TypedefType: case *dwarf.TypedefType:
// C has much more relaxed rules than Go for // C has much more relaxed rules than Go for
// implicit type conversions. When the parameter // implicit type conversions. When the parameter
...@@ -1406,7 +1377,7 @@ func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { ...@@ -1406,7 +1377,7 @@ func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
// FuncType returns the Go type analogous to dtype. // FuncType returns the Go type analogous to dtype.
// There is no guarantee about matching memory layout. // There is no guarantee about matching memory layout.
func (c *typeConv) FuncType(name *Name, dtype *dwarf.FuncType, pos token.Pos) *FuncType { func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
p := make([]*Type, len(dtype.ParamType)) p := make([]*Type, len(dtype.ParamType))
gp := make([]*ast.Field, len(dtype.ParamType)) gp := make([]*ast.Field, len(dtype.ParamType))
for i, f := range dtype.ParamType { for i, f := range dtype.ParamType {
...@@ -1420,10 +1391,6 @@ func (c *typeConv) FuncType(name *Name, dtype *dwarf.FuncType, pos token.Pos) *F ...@@ -1420,10 +1391,6 @@ func (c *typeConv) FuncType(name *Name, dtype *dwarf.FuncType, pos token.Pos) *F
break break
} }
p[i] = c.FuncArg(f, pos) p[i] = c.FuncArg(f, pos)
// See comment on usesSizeT.
if id, ok := p[i].Go.(*ast.Ident); ok && id.Name == "_Ctype_ulong" && usesSizeT[name.C] {
p[i].Go = c.Ident("_Ctype_size_t")
}
gp[i] = &ast.Field{Type: p[i].Go} gp[i] = &ast.Field{Type: p[i].Go}
} }
var r *Type var r *Type
...@@ -1432,10 +1399,6 @@ func (c *typeConv) FuncType(name *Name, dtype *dwarf.FuncType, pos token.Pos) *F ...@@ -1432,10 +1399,6 @@ func (c *typeConv) FuncType(name *Name, dtype *dwarf.FuncType, pos token.Pos) *F
gr = []*ast.Field{{Type: c.goVoid}} gr = []*ast.Field{{Type: c.goVoid}}
} else if dtype.ReturnType != nil { } else if dtype.ReturnType != nil {
r = c.Type(dtype.ReturnType, pos) r = c.Type(dtype.ReturnType, pos)
// See comment on usesSizeT.
if id, ok := r.Go.(*ast.Ident); ok && id.Name == "_Ctype_ulong" && usesSizeT[name.C] {
r.Go = c.Ident("_Ctype_size_t")
}
gr = []*ast.Field{{Type: r.Go}} gr = []*ast.Field{{Type: r.Go}}
} }
return &FuncType{ return &FuncType{
......
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