diff options
| author | gingerBill <bill@gingerbill.org> | 2024-04-24 17:28:00 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-04-24 17:31:31 +0100 |
| commit | 94d35d9918a8ce8b3686dba52bab3e468b46729d (patch) | |
| tree | 4c34a9204ff67a9e5a49bb2474173ea37513ebcc /src | |
| parent | 04278cd6548ccb79f01ffbf25141fdf21969d3e6 (diff) | |
Disallow mixing endian types within a `bit_field`
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_type.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp index 77ac91c38..ab8c0b057 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1101,6 +1101,45 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, gb_string_free(s); } + enum EndianKind { + Endian_Unknown, + Endian_Native, + Endian_Little, + Endian_Big, + }; + auto const &determine_endian_kind = [](Type *type) -> EndianKind { + if (is_type_boolean(type)) { + // NOTE(bill): it doesn't matter, and when it does, + // that api is absolutely stupid + return Endian_Unknown; + } else if (is_type_endian_specific(type)) { + if (is_type_endian_little(type)) { + return Endian_Little; + } else { + return Endian_Big; + } + } + return Endian_Native; + }; + + EndianKind backing_type_endian_kind = determine_endian_kind(core_array_type(backing_type)); + EndianKind endian_kind = Endian_Unknown; + for (Entity *f : fields) { + EndianKind field_kind = determine_endian_kind(f->type); + + if (field_kind && backing_type_endian_kind != field_kind) { + error(f->token, "All 'bit_field' field types must match the same endian kind as the backing type, i.e. all native, all little, or all big"); + } + + if (endian_kind == Endian_Unknown) { + endian_kind = field_kind; + } else if (field_kind && endian_kind != field_kind) { + error(f->token, "All 'bit_field' field types must be of the same endian variety, i.e. all native, all little, or all big"); + } + } + + + if (bit_sizes.count > 0 && is_type_integer(backing_type)) { bool all_booleans = is_type_boolean(fields[0]->type); bool all_ones = bit_sizes[0] == 1; |