If the aligned offset isn't sufficient for the field offset,
we were padding based on the aligned offset. We need to pad
based on the original offset instead.
Also set the Go alignment correctly for int128. We were defaulting
to the maximum alignment, but since we translate int128 into an
array of uint8 the correct Go alignment is 1.
For #69086
Fixes #69219
Change-Id: I23ce583335c81beac2ac51f7f9336ac97ccebf09
Reviewed-on: https://go-review.googlesource.com/c/go/+/608815
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit
c2098929056481d0dc09f5f42b8959f4db8878f2)
Reviewed-on: https://go-review.googlesource.com/c/go/+/611296
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
if dt.BitSize > 0 {
fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
}
+
+ if t.Align = t.Size; t.Align >= c.ptrSize {
+ t.Align = c.ptrSize
+ }
+
switch t.Size {
default:
fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
Len: c.intExpr(t.Size),
Elt: c.uint8,
}
- }
- if t.Align = t.Size; t.Align >= c.ptrSize {
- t.Align = c.ptrSize
+ // t.Align is the alignment of the Go type.
+ t.Align = 1
}
case *dwarf.PtrType:
if dt.BitSize > 0 {
fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
}
+
+ if t.Align = t.Size; t.Align >= c.ptrSize {
+ t.Align = c.ptrSize
+ }
+
switch t.Size {
default:
fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
Len: c.intExpr(t.Size),
Elt: c.uint8,
}
- }
- if t.Align = t.Size; t.Align >= c.ptrSize {
- t.Align = c.ptrSize
+ // t.Align is the alignment of the Go type.
+ t.Align = 1
}
case *dwarf.VoidType:
}
// Round off up to talign, assumed to be a power of 2.
+ origOff := off
off = (off + talign - 1) &^ (talign - 1)
if f.ByteOffset > off {
- fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
+ fld, sizes = c.pad(fld, sizes, f.ByteOffset-origOff)
off = f.ByteOffset
}
if f.ByteOffset < off {
func Test42018(t *testing.T) { test42018(t) }
func Test45451(t *testing.T) { test45451(t) }
func Test49633(t *testing.T) { test49633(t) }
+func Test69086(t *testing.T) { test69086(t) }
func TestAlign(t *testing.T) { testAlign(t) }
func TestAtol(t *testing.T) { testAtol(t) }
func TestBlocking(t *testing.T) { testBlocking(t) }
} issue67517struct;
static void issue67517(issue67517struct* p) {}
+// Issue 69086.
+// GCC added the __int128 type in GCC 4.6, released in 2011.
+typedef struct {
+ int a;
+#ifdef __SIZEOF_INT128__
+ unsigned __int128 b;
+#else
+ uint64_t b;
+#endif
+ unsigned char c;
+} 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); }
*/
import "C"
b: nil,
})
}
+
+// Issue 69086.
+func test69086(t *testing.T) {
+ var s C.issue69086struct
+
+ typ := reflect.TypeOf(s)
+ for i := 0; i < typ.NumField(); i++ {
+ f := typ.Field(i)
+ t.Logf("field %d: name %s size %d align %d offset %d", i, f.Name, f.Type.Size(), f.Type.Align(), f.Offset)
+ }
+
+ s.c = 1
+ got := C.issue690861(&s)
+ if got != 1 {
+ t.Errorf("field: got %d, want 1", got)
+ }
+ got = C.issue690862(1, 2, 3, s)
+ if got != 1234 {
+ t.Errorf("call: got %d, want 1234", got)
+ }
+}