Skip to content

Commit 73e8e46

Browse files
committed
casting between C pointers and normal pointers
See #1059
1 parent b8cbe38 commit 73e8e46

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

src/ir.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,7 +2462,7 @@ static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *
24622462

24632463
ir_ref_instruction(type_value, irb->current_basic_block);
24642464

2465-
return &instruction->base;
2465+
return &instruction->base;
24662466
}
24672467

24682468
static 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
67396739
atomic_state_field_name);
67406740

67416741
// 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,
67436743
usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr,
67446744
AtomicRmwOp_or, AtomicOrderSeqCst);
67456745

@@ -6817,7 +6817,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode
68176817
atomic_state_field_name);
68186818

68196819
// 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,
68216821
usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr,
68226822
AtomicRmwOp_and, AtomicOrderSeqCst);
68236823

@@ -6933,7 +6933,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
69336933

69346934
IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle);
69356935
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,
69376937
usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr,
69386938
AtomicRmwOp_or, AtomicOrderSeqCst);
69396939

@@ -6976,7 +6976,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
69766976

69776977

69786978
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,
69806980
usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr,
69816981
AtomicRmwOp_or, AtomicOrderSeqCst);
69826982
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
70087008

70097009
ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
70107010
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,
70127012
usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr,
70137013
AtomicRmwOp_or, AtomicOrderSeqCst);
70147014
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
1127911279
return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type);
1128011280
}
1128111281

11282-
// casting to C pointers
11283-
if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC) {
11284-
// cast from integer to C pointer
11285-
if (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt) {
11286-
return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
11287-
}
11282+
// casting between C pointers and normal pointers
11283+
if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer &&
11284+
(wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) &&
11285+
types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
11286+
actual_type->data.pointer.child_type, source_node,
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);
1128811297
}
1128911298

1129011299
// cast from undefined to anything
@@ -16436,7 +16445,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1643616445
pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node);
1643716446
if (pointee_val == nullptr)
1643816447
return ira->codegen->invalid_instruction;
16439-
16448+
1644016449
if (pointee_val->special == ConstValSpecialRuntime)
1644116450
pointee_val = nullptr;
1644216451
}
@@ -17186,7 +17195,7 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
1718617195
static TypeStructField *validate_byte_offset(IrAnalyze *ira,
1718717196
IrInstruction *type_value,
1718817197
IrInstruction *field_name_value,
17189-
size_t *byte_offset)
17198+
size_t *byte_offset)
1719017199
{
1719117200
ZigType *container_type = ir_resolve_type(ira, type_value);
1719217201
if (type_is_invalid(container_type))
@@ -17360,7 +17369,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
1736017369

1736117370
// Loop through the definitions and generate info.
1736217371
decl_it = decls_scope->decl_table.entry_iterator();
17363-
curr_entry = nullptr;
17372+
curr_entry = nullptr;
1736417373
int definition_index = 0;
1736517374
while ((curr_entry = decl_it.next()) != nullptr) {
1736617375
// Skip comptime blocks and test functions.
@@ -20312,7 +20321,7 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
2031220321
} else {
2031320322
seenFalse += 1;
2031420323
}
20315-
20324+
2031620325
if ((seenTrue > 1) || (seenFalse > 1)) {
2031720326
ir_add_error(ira, value, buf_sprintf("duplicate switch value"));
2031820327
return ira->codegen->invalid_instruction;

test/stage1/behavior/pointers.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@ test "assigning integer to C pointer" {
4848
var ptr: [*c]u8 = 0;
4949
var ptr2: [*c]u8 = x;
5050
}
51+
52+
test "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+
}

0 commit comments

Comments
 (0)