aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-02-22 20:10:56 +0000
committergingerBill <bill@gingerbill.org>2024-02-22 20:10:56 +0000
commit9ea11da00f65a7b69c2cdf55bc7625713e0bd374 (patch)
tree4a29fff87d4281a973f4c8cc3a0f8de861f2b8ea /src
parenta8909f06aea541860339c8c95f2bc8fe3f637a87 (diff)
Add warning when using `bit_field` when a `bit_set` would be a much better idea.
Diffstat (limited to 'src')
-rw-r--r--src/check_type.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 1bcae140f..6e10798f3 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -1016,6 +1016,11 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
if (o.value.kind == ExactValue_Float) {
o.value = exact_value_to_integer(o.value);
}
+ if (f->bit_size->kind == Ast_BinaryExpr && f->bit_size->BinaryExpr.op.kind == Token_Or) {
+ gbString s = expr_to_string(f->bit_size);
+ error(f->bit_size, "Wrap the expression in parentheses, e.g. (%s)", s);
+ gb_string_free(s);
+ }
ExactValue bit_size = o.value;
@@ -1076,7 +1081,6 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
curr_offset += cast(i64)bit_sizes[i];
}
-
if (total_bit_size > maximum_bit_size) {
gbString s = type_to_string(backing_type);
error(node, "The numbers required %llu exceeds the backing type's (%s) bit size %llu",
@@ -1086,6 +1090,27 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
gb_string_free(s);
}
+ 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;
+ if (all_ones && all_booleans) {
+ for_array(i, bit_sizes) {
+ all_ones = bit_sizes[i] == 1;
+ if (!all_ones) {
+ break;
+ }
+ all_booleans = is_type_boolean(fields[i]->type);
+ if (!all_booleans) {
+ break;
+ }
+ }
+ if (all_ones && all_booleans) {
+ warning(node, "This 'bit_field' might be better expressed as a 'bit_set' since all of the fields are booleans, of 1-bit in size, and the backing type is an integer");
+ }
+ }
+ }
+
+
bit_field_type->BitField.fields = slice_from_array(fields);
bit_field_type->BitField.bit_sizes = slice_from_array(bit_sizes);
bit_field_type->BitField.bit_offsets = bit_offsets;