mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: strip top-level const qualifier from argument frame struct
Otherwise we can't assign to it. Fixes #75751 Change-Id: Iba680db672297bca1a1d1a33912b80863da66a08 Reviewed-on: https://go-review.googlesource.com/c/go/+/717342 Reviewed-by: David Chase <drchase@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: Mark Freeman <markfreeman@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
1903782ade
commit
9772d3a690
2 changed files with 43 additions and 2 deletions
|
|
@ -953,6 +953,12 @@ typedef struct {
|
|||
} issue69086struct;
|
||||
static int issue690861(issue69086struct* p) { p->b = 1234; return p->c; }
|
||||
static int issue690862(unsigned long ul1, unsigned long ul2, unsigned int u, issue69086struct s) { return (int)(s.b); }
|
||||
|
||||
char issue75751v = 1;
|
||||
char * const issue75751p = &issue75751v;
|
||||
#define issue75751m issue75751p
|
||||
char * const volatile issue75751p2 = &issue75751v;
|
||||
#define issue75751m2 issue75751p2
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
|
@ -2396,3 +2402,8 @@ func test69086(t *testing.T) {
|
|||
t.Errorf("call: got %d, want 1234", got)
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 75751: no runtime test, just make sure it compiles.
|
||||
func test75751() int {
|
||||
return int(*C.issue75751m) + int(*C.issue75751m2)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -457,6 +457,36 @@ func checkImportSymName(s string) {
|
|||
// Also assumes that gc convention is to word-align the
|
||||
// input and output parameters.
|
||||
func (p *Package) structType(n *Name) (string, int64) {
|
||||
// It's possible for us to see a type with a top-level const here,
|
||||
// which will give us an unusable struct type. See #75751.
|
||||
// The top-level const will always appear as a final qualifier,
|
||||
// constructed by typeConv.loadType in the dwarf.QualType case.
|
||||
// The top-level const is meaningless here and can simply be removed.
|
||||
stripConst := func(s string) string {
|
||||
i := strings.LastIndex(s, "const")
|
||||
if i == -1 {
|
||||
return s
|
||||
}
|
||||
|
||||
// A top-level const can only be followed by other qualifiers.
|
||||
if r, ok := strings.CutSuffix(s, "const"); ok {
|
||||
return strings.TrimSpace(r)
|
||||
}
|
||||
|
||||
var nonConst []string
|
||||
for _, f := range strings.Fields(s[i:]) {
|
||||
switch f {
|
||||
case "const":
|
||||
case "restrict", "volatile":
|
||||
nonConst = append(nonConst, f)
|
||||
default:
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
return strings.TrimSpace(s[:i]) + " " + strings.Join(nonConst, " ")
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
fmt.Fprint(&buf, "struct {\n")
|
||||
off := int64(0)
|
||||
|
|
@ -468,7 +498,7 @@ func (p *Package) structType(n *Name) (string, int64) {
|
|||
}
|
||||
c := t.Typedef
|
||||
if c == "" {
|
||||
c = t.C.String()
|
||||
c = stripConst(t.C.String())
|
||||
}
|
||||
fmt.Fprintf(&buf, "\t\t%s p%d;\n", c, i)
|
||||
off += t.Size
|
||||
|
|
@ -484,7 +514,7 @@ func (p *Package) structType(n *Name) (string, int64) {
|
|||
fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad)
|
||||
off += pad
|
||||
}
|
||||
fmt.Fprintf(&buf, "\t\t%s r;\n", t.C)
|
||||
fmt.Fprintf(&buf, "\t\t%s r;\n", stripConst(t.C.String()))
|
||||
off += t.Size
|
||||
}
|
||||
if off%p.PtrSize != 0 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue