aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-11-29 15:11:46 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-11-29 15:11:46 -0500
commit75b7ee2a08aefbdb2e2202718326fadd96ee0ef0 (patch)
treec5376b68b658398399c47d20a37b6acebaf1807f /src
parentbb2f890fd470fff3e42698710b56c68164491d85 (diff)
Fix for undefined behavior on structs/enums with paddingv2025-11-29.2
Diffstat (limited to 'src')
-rw-r--r--src/types.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/types.c b/src/types.c
index 04784735..6ed24f6c 100644
--- a/src/types.c
+++ b/src/types.c
@@ -459,15 +459,25 @@ PUREFUNC bool is_packed_data(type_t *t) {
|| t->tag == FunctionType) {
return true;
} else if (t->tag == StructType) {
+ size_t offset = 0;
for (arg_t *field = Match(t, StructType)->fields; field; field = field->next) {
if (!is_packed_data(field->type)) return false;
+ size_t align = type_align(field->type);
+ if (align > 0 && offset % align != 0) return false;
+ offset += type_size(field->type);
}
- return true;
+ size_t overall_align = type_align(t);
+ return overall_align == 0 || (offset % overall_align == 0);
} else if (t->tag == EnumType) {
+ size_t offset = sizeof(int32_t);
for (tag_t *tag = Match(t, EnumType)->tags; tag; tag = tag->next) {
if (!is_packed_data(tag->type)) return false;
+ size_t align = type_align(tag->type);
+ if (align > 0 && offset % align != 0) return false;
+ offset += type_size(tag->type);
}
- return true;
+ size_t overall_align = type_align(t);
+ return overall_align == 0 || (offset % overall_align == 0);
} else {
return false;
}