| // Copyright 2018 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // cgo was incorrectly adding padding after a packed struct. | |
| package cgotest | |
| /* | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #include <stdlib.h> | |
| typedef struct { | |
| void *f1; | |
| uint32_t f2; | |
| } __attribute__((__packed__)) innerPacked; | |
| typedef struct { | |
| innerPacked g1; | |
| uint64_t g2; | |
| } outerPacked; | |
| typedef struct { | |
| void *f1; | |
| uint32_t f2; | |
| } innerUnpacked; | |
| typedef struct { | |
| innerUnpacked g1; | |
| uint64_t g2; | |
| } outerUnpacked; | |
| size_t offset(int x) { | |
| switch (x) { | |
| case 0: | |
| return offsetof(innerPacked, f2); | |
| case 1: | |
| return offsetof(outerPacked, g2); | |
| case 2: | |
| return offsetof(innerUnpacked, f2); | |
| case 3: | |
| return offsetof(outerUnpacked, g2); | |
| default: | |
| abort(); | |
| } | |
| } | |
| */ | |
| import "C" | |
| import ( | |
| "testing" | |
| "unsafe" | |
| ) | |
| func offset(i int) uintptr { | |
| var pi C.innerPacked | |
| var po C.outerPacked | |
| var ui C.innerUnpacked | |
| var uo C.outerUnpacked | |
| switch i { | |
| case 0: | |
| return unsafe.Offsetof(pi.f2) | |
| case 1: | |
| return unsafe.Offsetof(po.g2) | |
| case 2: | |
| return unsafe.Offsetof(ui.f2) | |
| case 3: | |
| return unsafe.Offsetof(uo.g2) | |
| default: | |
| panic("can't happen") | |
| } | |
| } | |
| func test28896(t *testing.T) { | |
| for i := 0; i < 4; i++ { | |
| c := uintptr(C.offset(C.int(i))) | |
| g := offset(i) | |
| if c != g { | |
| t.Errorf("%d: C: %d != Go %d", i, c, g) | |
| } | |
| } | |
| } |