From 75b7ee2a08aefbdb2e2202718326fadd96ee0ef0 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 29 Nov 2025 15:11:46 -0500 Subject: Fix for undefined behavior on structs/enums with padding --- CHANGES.md | 6 ++++++ src/types.c | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 212fe54c..b4910bb8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Version History +## v2025-11-29.2 + +### Bugfixes + +- Fix for undefined behavior on enums and structs with padding. + ## v2025-11-29 ### Syntax changes 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; } -- cgit v1.2.3