aboutsummaryrefslogtreecommitdiff
path: root/src/check_type.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2019-05-19 10:45:27 +0100
committergingerBill <bill@gingerbill.org>2019-05-19 10:45:27 +0100
commitf5fdd031f9b763a2b6a86f2fc536735fc8d7ed5d (patch)
tree17b68598bfb521e944f9950634bca3275dae1b9b /src/check_type.cpp
parentceb58ae04f3073f2ba400143524240f4ed74b506 (diff)
Fix polymorphic procedure return by pointer values #374
Diffstat (limited to 'src/check_type.cpp')
-rw-r--r--src/check_type.cpp43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index bd3271dcf..1e05b295f 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -1237,6 +1237,9 @@ Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Oper
}
if (is_polymorphic_type_assignable(ctx, poly_type, operand.type, false, modify_type)) {
+ if (modify_type) {
+ set_procedure_abi_types(ctx, poly_type);
+ }
return poly_type;
}
if (modify_type) {
@@ -1980,8 +1983,8 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) {
new_type = tuple;
}
-
- // return reduce_tuple_to_single_type(new_type);
+ new_type->cached_size = -1;
+ new_type->cached_align = -1;
return new_type;
}
@@ -2013,6 +2016,27 @@ bool abi_compat_return_by_pointer(gbAllocator a, ProcCallingConvention cc, Type
return false;
}
+void set_procedure_abi_types(CheckerContext *c, Type *type) {
+ type = base_type(type);
+ if (type->kind != Type_Proc) {
+ return;
+ }
+
+ type->Proc.abi_compat_params = array_make<Type *>(c->allocator, cast(isize)type->Proc.param_count);
+ for (i32 i = 0; i < type->Proc.param_count; i++) {
+ Entity *e = type->Proc.params->Tuple.variables[i];
+ if (e->kind == Entity_Variable) {
+ Type *original_type = e->type;
+ Type *new_type = type_to_abi_compat_param_type(c->allocator, original_type);
+ type->Proc.abi_compat_params[i] = new_type;
+ }
+ }
+
+ // NOTE(bill): The types are the same
+ type->Proc.abi_compat_result_type = type_to_abi_compat_result_type(c->allocator, type->Proc.results);
+ type->Proc.return_by_pointer = abi_compat_return_by_pointer(c->allocator, type->Proc.calling_convention, type->Proc.abi_compat_result_type);
+}
+
// NOTE(bill): 'operands' is for generating non generic procedure type
bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array<Operand> *operands) {
ast_node(pt, ProcType, proc_type_node);
@@ -2108,20 +2132,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
}
type->Proc.is_polymorphic = is_polymorphic;
-
- type->Proc.abi_compat_params = array_make<Type *>(c->allocator, param_count);
- for (isize i = 0; i < param_count; i++) {
- Entity *e = type->Proc.params->Tuple.variables[i];
- if (e->kind == Entity_Variable) {
- Type *original_type = e->type;
- Type *new_type = type_to_abi_compat_param_type(c->allocator, original_type);
- type->Proc.abi_compat_params[i] = new_type;
- }
- }
-
- // NOTE(bill): The types are the same
- type->Proc.abi_compat_result_type = type_to_abi_compat_result_type(c->allocator, type->Proc.results);
- type->Proc.return_by_pointer = abi_compat_return_by_pointer(c->allocator, pt->calling_convention, type->Proc.abi_compat_result_type);
+ set_procedure_abi_types(c, type);
return success;
}