aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-06-16 21:13:10 -0400
committerGitHub <noreply@github.com>2018-06-16 21:13:10 -0400
commit751518787ae9772eb063a4911a10bf30b2c2a19c (patch)
tree4dd5a4613a04760571da1088648704ec3c72e353 /src/ir.cpp
parent3ee4d23ebdd149e734ca33904a4786d5bd3fa8aa (diff)
parent472b7ef7e6db4bdd4717ff5b44b63e233853bb06 (diff)
downloadzig-751518787ae9772eb063a4911a10bf30b2c2a19c.tar.gz
zig-751518787ae9772eb063a4911a10bf30b2c2a19c.zip
Merge pull request #1109 from ziglang/pass-by-non-copying-value
allow passing by non-copying value
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp57
1 files changed, 34 insertions, 23 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index e5e8dcbb9d..d008ead113 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -10463,13 +10463,6 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
zig_unreachable();
}
-static IrInstruction *ir_implicit_byval_const_ref_cast(IrAnalyze *ira, IrInstruction *inst) {
- if (type_is_copyable(ira->codegen, inst->value.type))
- return inst;
- TypeTableEntry *const_ref_type = get_pointer_to_type(ira->codegen, inst->value.type, true);
- return ir_implicit_cast(ira, inst, const_ref_type);
-}
-
static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {
TypeTableEntry *type_entry = ptr->value.type;
if (type_is_invalid(type_entry)) {
@@ -12283,7 +12276,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
IrInstruction *casted_arg;
if (is_var_args) {
arg_part_of_generic_id = true;
- casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
+ casted_arg = arg;
} else {
if (param_decl_node->data.param_decl.var_token == nullptr) {
AstNode *param_type_node = param_decl_node->data.param_decl.type;
@@ -12296,7 +12289,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
return false;
} else {
arg_part_of_generic_id = true;
- casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
+ casted_arg = arg;
}
}
@@ -12515,9 +12508,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
size_t next_proto_i = 0;
if (first_arg_ptr) {
- IrInstruction *first_arg;
assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
- if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
+
+ bool first_arg_known_bare = false;
+ if (fn_type_id->next_param_index >= 1) {
+ TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
+ if (type_is_invalid(param_type))
+ return ira->codegen->builtin_types.entry_invalid;
+ first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
+ }
+
+ IrInstruction *first_arg;
+ if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
first_arg = first_arg_ptr;
} else {
first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
@@ -12667,9 +12669,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
size_t next_proto_i = 0;
if (first_arg_ptr) {
- IrInstruction *first_arg;
assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
- if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
+
+ bool first_arg_known_bare = false;
+ if (fn_type_id->next_param_index >= 1) {
+ TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
+ if (type_is_invalid(param_type))
+ return ira->codegen->builtin_types.entry_invalid;
+ first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
+ }
+
+ IrInstruction *first_arg;
+ if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
first_arg = first_arg_ptr;
} else {
first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
@@ -12802,10 +12813,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
return ira->codegen->builtin_types.entry_invalid;
}
if (inst_fn_type_id.async_allocator_type == nullptr) {
- IrInstruction *casted_inst = ir_implicit_byval_const_ref_cast(ira, uncasted_async_allocator_inst);
- if (type_is_invalid(casted_inst->value.type))
- return ira->codegen->builtin_types.entry_invalid;
- inst_fn_type_id.async_allocator_type = casted_inst->value.type;
+ inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type;
}
async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type);
if (type_is_invalid(async_allocator_inst->value.type))
@@ -12866,9 +12874,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count);
size_t next_arg_index = 0;
if (first_arg_ptr) {
- IrInstruction *first_arg;
assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
- if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
+
+ TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
+ if (type_is_invalid(param_type))
+ return ira->codegen->builtin_types.entry_invalid;
+
+ IrInstruction *first_arg;
+ if (param_type->id == TypeTableEntryIdPointer &&
+ handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type))
+ {
first_arg = first_arg_ptr;
} else {
first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
@@ -12876,10 +12891,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
return ira->codegen->builtin_types.entry_invalid;
}
- TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
- if (type_is_invalid(param_type))
- return ira->codegen->builtin_types.entry_invalid;
-
IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type);
if (type_is_invalid(casted_arg->value.type))
return ira->codegen->builtin_types.entry_invalid;