diff --git a/cl/_testrt/structsize/in.go b/cl/_testrt/structsize/in.go new file mode 100644 index 00000000..0e83f67c --- /dev/null +++ b/cl/_testrt/structsize/in.go @@ -0,0 +1,19 @@ +package main + +import ( + "unsafe" + + "github.com/goplus/llgo/c" +) + +type Foo struct { + A byte + B uint8 + C uint16 + D byte + E [8]int8 +} + +func main() { + c.Printf(c.Str("%d"), unsafe.Sizeof(Foo{})) +} diff --git a/cl/_testrt/structsize/out.ll b/cl/_testrt/structsize/out.ll new file mode 100644 index 00000000..643a449e --- /dev/null +++ b/cl/_testrt/structsize/out.ll @@ -0,0 +1,34 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global i1 false, align 1 +@__llgo_argc = global i32 0, align 4 +@__llgo_argv = global ptr null, align 8 +@0 = private unnamed_addr constant [3 x i8] c"%d\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define i32 @main(i32 %0, ptr %1) { +_llgo_0: + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call i32 (ptr, ...) @printf(ptr @0, i64 14) + ret i32 0 +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare i32 @printf(ptr, ...) diff --git a/ssa/type.go b/ssa/type.go index 3b6e85f9..af48f47c 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -114,7 +114,11 @@ func (p *goProgram) Offsetsof(fields []*types.Var) (ret []int64) { func (p *goProgram) Sizeof(T types.Type) int64 { prog := Program(p) ptrSize := int64(prog.PointerSize()) - return prog.sizes.Sizeof(T) + extraSize(T, ptrSize) + baseSize := prog.sizes.Sizeof(T) + extraSize(T, ptrSize) + if _, ok := T.Underlying().(*types.Struct); ok { + return align(baseSize, prog.sizes.Alignof(T)) + } + return baseSize } func extraSize(t types.Type, ptrSize int64) (ret int64) { @@ -134,6 +138,10 @@ func extraSize(t types.Type, ptrSize int64) (ret int64) { return 0 } +func align(x, a int64) int64 { + return (x + a - 1) &^ (a - 1) +} + // ----------------------------------------------------------------------------- type rawType struct {