aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-04-24 17:28:00 +0100
committergingerBill <bill@gingerbill.org>2024-04-24 17:31:31 +0100
commit94d35d9918a8ce8b3686dba52bab3e468b46729d (patch)
tree4c34a9204ff67a9e5a49bb2474173ea37513ebcc /src
parent04278cd6548ccb79f01ffbf25141fdf21969d3e6 (diff)
Disallow mixing endian types within a `bit_field`
Diffstat (limited to 'src')
-rw-r--r--src/check_type.cpp39
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;