aboutsummaryrefslogtreecommitdiff
path: root/src/check_builtin.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-07-01 12:13:35 +0100
committergingerBill <bill@gingerbill.org>2024-07-01 12:13:35 +0100
commit544959326b467b6587a04d6211ea142de932109c (patch)
treef00aa354b20732a8ab90d745a043e66ed6362bf3 /src/check_builtin.cpp
parent942f3f52207e32f68a9342ba2693f3b37199937b (diff)
Add `intrinsics.type_struct_has_implicit_padding` #3844
Diffstat (limited to 'src/check_builtin.cpp')
-rw-r--r--src/check_builtin.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index c1422e80e..7a1a8b9ee 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -5839,6 +5839,31 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
operand->mode = Addressing_Constant;
operand->type = t_untyped_integer;
break;
+ case BuiltinProc_type_struct_has_implicit_padding:
+ operand->value = exact_value_bool(false);
+ if (operand->mode != Addressing_Type) {
+ error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name));
+ } else if (!is_type_struct(operand->type) && !is_type_soa_struct(operand->type)) {
+ error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name));
+ } else {
+ Type *bt = base_type(operand->type);
+ if (bt->Struct.is_packed) {
+ operand->value = exact_value_bool(false);
+ } else if (bt->Struct.fields.count != 0) {
+ i64 size = type_size_of(bt);
+ Type *field_type = nullptr;
+ i64 last_offset = type_offset_of(bt, bt->Struct.fields.count-1, &field_type);
+ if (last_offset+type_size_of(field_type) < size) {
+ operand->value = exact_value_bool(true);
+ } else {
+ i64 packed_size = type_size_of_struct_pretend_is_packed(bt);
+ operand->value = exact_value_bool(packed_size < size);
+ }
+ }
+ }
+ operand->mode = Addressing_Constant;
+ operand->type = t_untyped_bool;
+ break;
case BuiltinProc_type_proc_parameter_count:
operand->value = exact_value_i64(0);