aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-09-30 10:47:31 +0100
committergingerBill <gingerBill@users.noreply.github.com>2025-09-30 10:47:31 +0100
commit668df4a571cdc376a6a13992364f6debf09f0476 (patch)
tree39e99c4c20a2703665343a49319dedf66076fda7 /src
parent748b4cdc6b05827efb14a099340fff096c85bcc6 (diff)
Improve `signature_parameter_similar_enough` for structs
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index f7df73953..779dd6c12 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -853,10 +853,40 @@ gb_internal bool signature_parameter_similar_enough(Type *x, Type *y) {
Type *x_base = base_type(x);
Type *y_base = base_type(y);
- if (x_base->kind == y_base->kind && x_base->kind == Type_Struct) {
- return type_size_of(x_base) == type_size_of(y_base) && type_align_of(x_base) == type_align_of(y_base);
+ if (x_base->kind == y_base->kind &&
+ x_base->kind == Type_Struct) {
+ i64 xs = type_size_of(x_base);
+ i64 ys = type_size_of(y_base);
+
+ i64 xa = type_align_of(x_base);
+ i64 ya = type_align_of(y_base);
+
+
+ if (x_base->Struct.is_raw_union == y_base->Struct.is_raw_union &&
+ xs == ys && xa == ya) {
+ if (xs > 16) {
+ // @@ABI NOTE(bill): Just allow anything over 16-bytes to be allowed, because on all current ABIs
+ // it will be passed by point
+ // NOTE(bill): this must be changed when ABI changes
+ return true;
+ }
+ if (x->Struct.fields.count == y->Struct.fields.count) {
+ for (isize i = 0; i < x->Struct.fields.count; i++) {
+ Entity *a = x->Struct.fields[i];
+ Entity *b = y->Struct.fields[i];
+ bool similar = signature_parameter_similar_enough(a->type, b->type);
+ if (!similar) {
+ // NOTE(bill): If the fields are not similar enough, then stop.
+ goto end;
+ }
+ }
+ }
+ // HACK NOTE(bill): Allow this for the time begin until it actually becomes a practical problem
+ return true;
+ }
}
+end:;
return are_types_identical(x, y);
}