roc-lang / roc

A fast, friendly, functional language.
https://roc-lang.org
Universal Permissive License v1.0
4.39k stars 309 forks source link

Incorrect C-convention llvm codegen for big union #2803

Open ayazhafiz opened 2 years ago

ayazhafiz commented 2 years ago

For Elem in the following code

Rgba : { r : F32, g : F32, b : F32, a : F32 }

ButtonStyles : { bgColor : Rgba, borderColor : Rgba, borderWidth : F32, textColor : Rgba }

Elem : [ Rect ButtonStyles, Text Str ]

We generate a struct with layout

{ { [6 x i64], [4 x i8] }, i8 }

That is, packed to exactly 52 bytes for the ButtonStyles payload, and one byte for the discriminant.

But C expects a 64-byte union (aligned at 16 bytes), if we were to treat the payloads of Elem as a proper union. See https://godbolt.org/z/MT3Efjzzv.

Two ways to resolve this:

rtfeldman commented 2 years ago

This can be reproduced by going to the commit before 7b5bc8e85ff32f481a6af728219cab7d5fc0e78a and running cargo run examples/breakout/breakout.roc