mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: use C exact-width integer types to represent Go types
The exact-width integer types are required to use two’s complement
representation and may not have padding bits, cf. §7.20.1.1/1 in the C11
standard or https://en.cppreference.com/w/c/types/integer. This ensures that
they have the same domain and representation as the corresponding Go types.
Fixes #29878
Change-Id: Ie8a51e91666dfd89731c7859abe47356c94ca1be
GitHub-Last-Rev: 546a2cc3f1
GitHub-Pull-Request: golang/go#29907
Reviewed-on: https://go-review.googlesource.com/c/go/+/159258
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
7b916243d9
commit
08751259b7
6 changed files with 89 additions and 22 deletions
|
|
@ -23,6 +23,7 @@ import (
|
|||
"internal/xcoff"
|
||||
"math"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
|
@ -2046,6 +2047,8 @@ type typeConv struct {
|
|||
|
||||
ptrSize int64
|
||||
intSize int64
|
||||
|
||||
exactWidthIntegerTypes map[string]*Type
|
||||
}
|
||||
|
||||
var tagGen int
|
||||
|
|
@ -2088,6 +2091,21 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
|
|||
} else {
|
||||
c.goVoidPtr = c.Ident("unsafe.Pointer")
|
||||
}
|
||||
|
||||
c.exactWidthIntegerTypes = make(map[string]*Type)
|
||||
for _, t := range []ast.Expr{
|
||||
c.int8, c.int16, c.int32, c.int64,
|
||||
c.uint8, c.uint16, c.uint32, c.uint64,
|
||||
} {
|
||||
name := t.(*ast.Ident).Name
|
||||
u := new(Type)
|
||||
*u = *goTypes[name]
|
||||
if u.Align > ptrSize {
|
||||
u.Align = ptrSize
|
||||
}
|
||||
u.Go = t
|
||||
c.exactWidthIntegerTypes[name] = u
|
||||
}
|
||||
}
|
||||
|
||||
// base strips away qualifiers and typedefs to get the underlying type
|
||||
|
|
@ -2459,6 +2477,24 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
|||
t.Align = c.ptrSize
|
||||
break
|
||||
}
|
||||
// Exact-width integer types. These are always compatible with
|
||||
// the corresponding Go types since the C standard requires
|
||||
// them to have no padding bit and use the two’s complement
|
||||
// representation.
|
||||
if exactWidthIntegerType.MatchString(dt.Name) {
|
||||
sub := c.Type(dt.Type, pos)
|
||||
u := c.exactWidthIntegerTypes[strings.TrimSuffix(dt.Name, "_t")]
|
||||
if sub.Size != u.Size {
|
||||
fatalf("%s: unexpected size: %d vs. %d – %s", lineno(pos), sub.Size, u.Size, dtype)
|
||||
}
|
||||
if sub.Align != u.Align {
|
||||
fatalf("%s: unexpected alignment: %d vs. %d – %s", lineno(pos), sub.Align, u.Align, dtype)
|
||||
}
|
||||
t.Size = u.Size
|
||||
t.Align = u.Align
|
||||
t.Go = u.Go
|
||||
break
|
||||
}
|
||||
name := c.Ident("_Ctype_" + dt.Name)
|
||||
goIdent[name.Name] = name
|
||||
sub := c.Type(dt.Type, pos)
|
||||
|
|
@ -2594,6 +2630,8 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
|||
return t
|
||||
}
|
||||
|
||||
var exactWidthIntegerType = regexp.MustCompile(`^u?int(8|16|32|64)_t$`)
|
||||
|
||||
// isStructUnionClass reports whether the type described by the Go syntax x
|
||||
// is a struct, union, or class with a tag.
|
||||
func isStructUnionClass(x ast.Expr) bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue