authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-10 01:11:30-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-10 01:11:40-05:00
log73e8e46257ac8f34e941a357a860d19e0d38dbac
tree545a4352c65ff9ec84d470a04200ad85c9871b84
parentb8cbe3872e702ab8ec388e75cb711330a45825b0
signature Commit is signed but in an unrecognized format.

casting between C pointers and normal pointers

See #1059

2 files changed, 33 insertions(+), 16 deletions(-)

src/ir.cpp+25-16
...@@ -2462,7 +2462,7 @@ static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *...@@ -2462,7 +2462,7 @@ static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *
24622462
2463 ir_ref_instruction(type_value, irb->current_basic_block);2463 ir_ref_instruction(type_value, irb->current_basic_block);
24642464
2465 return &instruction->base; 2465 return &instruction->base;
2466}2466}
24672467
2468static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node,2468static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node,
...@@ -6739,7 +6739,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode...@@ -6739,7 +6739,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode
6739 atomic_state_field_name);6739 atomic_state_field_name);
67406740
6741 // set the is_canceled bit6741 // set the is_canceled bit
6742 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6742 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
6743 usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr,6743 usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr,
6744 AtomicRmwOp_or, AtomicOrderSeqCst);6744 AtomicRmwOp_or, AtomicOrderSeqCst);
67456745
...@@ -6817,7 +6817,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode...@@ -6817,7 +6817,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode
6817 atomic_state_field_name);6817 atomic_state_field_name);
68186818
6819 // clear the is_suspended bit6819 // clear the is_suspended bit
6820 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6820 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
6821 usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr,6821 usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr,
6822 AtomicRmwOp_and, AtomicOrderSeqCst);6822 AtomicRmwOp_and, AtomicOrderSeqCst);
68236823
...@@ -6933,7 +6933,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -6933,7 +6933,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
69336933
6934 IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle);6934 IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle);
6935 IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false);6935 IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false);
6936 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6936 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
6937 usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr,6937 usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr,
6938 AtomicRmwOp_or, AtomicOrderSeqCst);6938 AtomicRmwOp_or, AtomicOrderSeqCst);
69396939
...@@ -6976,7 +6976,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -6976,7 +6976,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
69766976
69776977
6978 ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block);6978 ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block);
6979 IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6979 IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
6980 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr,6980 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr,
6981 AtomicRmwOp_or, AtomicOrderSeqCst);6981 AtomicRmwOp_or, AtomicOrderSeqCst);
6982 IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false);6982 IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false);
...@@ -7008,7 +7008,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -7008,7 +7008,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
70087008
7009 ir_set_cursor_at_end_and_append_block(irb, cleanup_block);7009 ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
7010 IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false);7010 IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false);
7011 IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7011 IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
7012 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr,7012 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr,
7013 AtomicRmwOp_or, AtomicOrderSeqCst);7013 AtomicRmwOp_or, AtomicOrderSeqCst);
7014 IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false);7014 IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false);
...@@ -11279,12 +11279,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11279,12 +11279,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11279 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type);11279 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type);
11280 }11280 }
1128111281
11282 // casting to C pointers11282 // casting between C pointers and normal pointers
11283 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC) {11283 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer &&
11284 // cast from integer to C pointer11284 (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) &&
11285 if (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt) {11285 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
11286 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);11286 actual_type->data.pointer.child_type, source_node,
11287 }11287 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
11288 {
11289 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr);
11290 }
11291
11292 // cast from integer to C pointer
11293 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC &&
11294 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt))
11295 {
11296 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
11288 }11297 }
1128911298
11290 // cast from undefined to anything11299 // cast from undefined to anything
...@@ -16436,7 +16445,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -16436,7 +16445,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
16436 pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node);16445 pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node);
16437 if (pointee_val == nullptr)16446 if (pointee_val == nullptr)
16438 return ira->codegen->invalid_instruction;16447 return ira->codegen->invalid_instruction;
16439 16448
16440 if (pointee_val->special == ConstValSpecialRuntime)16449 if (pointee_val->special == ConstValSpecialRuntime)
16441 pointee_val = nullptr;16450 pointee_val = nullptr;
16442 }16451 }
...@@ -17186,7 +17195,7 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,...@@ -17186,7 +17195,7 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
17186static TypeStructField *validate_byte_offset(IrAnalyze *ira,17195static TypeStructField *validate_byte_offset(IrAnalyze *ira,
17187 IrInstruction *type_value,17196 IrInstruction *type_value,
17188 IrInstruction *field_name_value,17197 IrInstruction *field_name_value,
17189 size_t *byte_offset) 17198 size_t *byte_offset)
17190{17199{
17191 ZigType *container_type = ir_resolve_type(ira, type_value);17200 ZigType *container_type = ir_resolve_type(ira, type_value);
17192 if (type_is_invalid(container_type))17201 if (type_is_invalid(container_type))
...@@ -17360,7 +17369,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco...@@ -17360,7 +17369,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
1736017369
17361 // Loop through the definitions and generate info.17370 // Loop through the definitions and generate info.
17362 decl_it = decls_scope->decl_table.entry_iterator();17371 decl_it = decls_scope->decl_table.entry_iterator();
17363 curr_entry = nullptr; 17372 curr_entry = nullptr;
17364 int definition_index = 0;17373 int definition_index = 0;
17365 while ((curr_entry = decl_it.next()) != nullptr) {17374 while ((curr_entry = decl_it.next()) != nullptr) {
17366 // Skip comptime blocks and test functions.17375 // Skip comptime blocks and test functions.
...@@ -20312,7 +20321,7 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,...@@ -20312,7 +20321,7 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
20312 } else {20321 } else {
20313 seenFalse += 1;20322 seenFalse += 1;
20314 }20323 }
20315 20324
20316 if ((seenTrue > 1) || (seenFalse > 1)) {20325 if ((seenTrue > 1) || (seenFalse > 1)) {
20317 ir_add_error(ira, value, buf_sprintf("duplicate switch value"));20326 ir_add_error(ira, value, buf_sprintf("duplicate switch value"));
20318 return ira->codegen->invalid_instruction;20327 return ira->codegen->invalid_instruction;
test/stage1/behavior/pointers.zig+8
...@@ -48,3 +48,11 @@ test "assigning integer to C pointer" {...@@ -48,3 +48,11 @@ test "assigning integer to C pointer" {
48 var ptr: [*c]u8 = 0;48 var ptr: [*c]u8 = 0;
49 var ptr2: [*c]u8 = x;49 var ptr2: [*c]u8 = x;
50}50}
51
52test "implicit cast single item pointer to C pointer and back" {
53 var y: u8 = 11;
54 var x: [*c]u8 = &y;
55 var z: *u8 = x;
56 z.* += 1;
57 expect(y == 12);
58}