summaryrefslogtreecommitdiff
path: root/dev-lang/go/files/go-1.25-strip-top-level-const.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dev-lang/go/files/go-1.25-strip-top-level-const.patch')
-rw-r--r--dev-lang/go/files/go-1.25-strip-top-level-const.patch94
1 files changed, 94 insertions, 0 deletions
diff --git a/dev-lang/go/files/go-1.25-strip-top-level-const.patch b/dev-lang/go/files/go-1.25-strip-top-level-const.patch
new file mode 100644
index 000000000000..1531263e3ed7
--- /dev/null
+++ b/dev-lang/go/files/go-1.25-strip-top-level-const.patch
@@ -0,0 +1,94 @@
+From 7a6e3f07acfd822aa1d62f1c715125e30d67d089 Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor <iant@golang.org>
+Date: Mon, 03 Nov 2025 15:54:39 -0800
+Subject: [PATCH] cmd/cgo: strip top-level const qualifier from argument frame struct
+
+Otherwise we can't assign to it.
+
+Fixes #75751
+
+Change-Id: Iba680db672297bca1a1d1a33912b80863da66a08
+---
+
+diff --git a/src/cmd/cgo/internal/test/test.go b/src/cmd/cgo/internal/test/test.go
+index 9626407..e83e367 100644
+--- a/src/cmd/cgo/internal/test/test.go
++++ b/src/cmd/cgo/internal/test/test.go
+@@ -953,6 +953,12 @@
+ } 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 @@
+ 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)
++}
+diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
+index 394e766..05d9dcf 100644
+--- a/src/cmd/cgo/out.go
++++ b/src/cmd/cgo/out.go
+@@ -457,6 +457,33 @@
+ // 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 r
++ }
++
++ for _, f := range strings.Fields(s[i:]) {
++ switch f {
++ case "const", "restrict", "volatile":
++ default:
++ return s
++ }
++ }
++
++ return strings.TrimSpace(s[:i]) + strings.TrimSpace(s[i+len("const"):])
++ }
++
+ var buf strings.Builder
+ fmt.Fprint(&buf, "struct {\n")
+ off := int64(0)
+@@ -468,7 +495,7 @@
+ }
+ 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 +511,7 @@
+ 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 {