Skip to content

Commit f8e63c4

Browse files
committed
change @bitcast to @ptrcast
See #290
1 parent 3ca027c commit f8e63c4

15 files changed

+90
-81
lines changed

doc/langref.md

+2-5
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,6 @@ calls the public `panic` function exposed in the root source file, or
634634
if there is not one specified, invokes the one provided in
635635
`std/special/panic.zig`.
636636

637-
### @bitcast(comptime DestType: type, value: var) -> DestType
637+
### @ptrcast(comptime DestType: type, value: var) -> DestType
638638

639-
Transmutes memory from one type to another without changing any bits.
640-
The source and destination types must have the same size. This function
641-
can be used to, for example, reinterpret a pointer, or convert a `f32` to a
642-
`u32`.
639+
Converts a pointer of one type to a pointer of another type.

src/all_types.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@ enum BuiltinFnId {
11961196
BuiltinFnIdSetGlobalSection,
11971197
BuiltinFnIdSetGlobalLinkage,
11981198
BuiltinFnIdPanic,
1199-
BuiltinFnIdBitCast,
1199+
BuiltinFnIdPtrCast,
12001200
};
12011201

12021202
struct BuiltinFnEntry {
@@ -1720,7 +1720,7 @@ enum IrInstructionId {
17201720
IrInstructionIdFnProto,
17211721
IrInstructionIdTestComptime,
17221722
IrInstructionIdInitEnum,
1723-
IrInstructionIdBitCast,
1723+
IrInstructionIdPtrCast,
17241724
IrInstructionIdWidenOrShorten,
17251725
IrInstructionIdIntToPtr,
17261726
IrInstructionIdPtrToInt,
@@ -2370,11 +2370,11 @@ struct IrInstructionInitEnum {
23702370
LLVMValueRef tmp_ptr;
23712371
};
23722372

2373-
struct IrInstructionBitCast {
2373+
struct IrInstructionPtrCast {
23742374
IrInstruction base;
23752375

23762376
IrInstruction *dest_type;
2377-
IrInstruction *target;
2377+
IrInstruction *ptr;
23782378
};
23792379

23802380
struct IrInstructionWidenOrShorten {

src/codegen.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
13451345
zig_unreachable();
13461346
}
13471347

1348-
static LLVMValueRef ir_render_bitcast(CodeGen *g, IrExecutable *executable,
1349-
IrInstructionBitCast *instruction)
1348+
static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
1349+
IrInstructionPtrCast *instruction)
13501350
{
13511351
TypeTableEntry *wanted_type = instruction->base.value.type;
1352-
LLVMValueRef target = ir_llvm_value(g, instruction->target);
1353-
return LLVMBuildBitCast(g->builder, target, wanted_type->type_ref, "");
1352+
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
1353+
return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
13541354
}
13551355

13561356
static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
@@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
27762776
return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
27772777
case IrInstructionIdStructInit:
27782778
return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
2779-
case IrInstructionIdBitCast:
2780-
return ir_render_bitcast(g, executable, (IrInstructionBitCast *)instruction);
2779+
case IrInstructionIdPtrCast:
2780+
return ir_render_ptr_cast(g, executable, (IrInstructionPtrCast *)instruction);
27812781
case IrInstructionIdWidenOrShorten:
27822782
return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
27832783
case IrInstructionIdPtrToInt:
@@ -4260,7 +4260,7 @@ static void define_builtin_fns(CodeGen *g) {
42604260
create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
42614261
create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
42624262
create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
4263-
create_builtin_fn(g, BuiltinFnIdBitCast, "bitcast", 2);
4263+
create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrcast", 2);
42644264
}
42654265

42664266
static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {

src/ir.cpp

+36-34
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
480480
return IrInstructionIdInitEnum;
481481
}
482482

483-
static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
484-
return IrInstructionIdBitCast;
483+
static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCast *) {
484+
return IrInstructionIdPtrCast;
485485
}
486486

487487
static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
@@ -1940,16 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old
19401940
return new_instruction;
19411941
}
19421942

1943-
static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
1944-
IrInstruction *dest_type, IrInstruction *target)
1943+
static IrInstruction *ir_build_ptr_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
1944+
IrInstruction *dest_type, IrInstruction *ptr)
19451945
{
1946-
IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(
1946+
IrInstructionPtrCast *instruction = ir_build_instruction<IrInstructionPtrCast>(
19471947
irb, scope, source_node);
19481948
instruction->dest_type = dest_type;
1949-
instruction->target = target;
1949+
instruction->ptr = ptr;
19501950

19511951
if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
1952-
ir_ref_instruction(target, irb->current_basic_block);
1952+
ir_ref_instruction(ptr, irb->current_basic_block);
19531953

19541954
return &instruction->base;
19551955
}
@@ -2666,12 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins
26662666
}
26672667
}
26682668

2669-
static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
2669+
static IrInstruction *ir_instruction_ptrcast_get_dep(IrInstructionPtrCast *instruction,
26702670
size_t index)
26712671
{
26722672
switch (index) {
26732673
case 0: return instruction->dest_type;
2674-
case 1: return instruction->target;
2674+
case 1: return instruction->ptr;
26752675
default: return nullptr;
26762676
}
26772677
}
@@ -2928,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
29282928
return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
29292929
case IrInstructionIdInitEnum:
29302930
return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
2931-
case IrInstructionIdBitCast:
2932-
return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
2931+
case IrInstructionIdPtrCast:
2932+
return ir_instruction_ptrcast_get_dep((IrInstructionPtrCast *) instruction, index);
29332933
case IrInstructionIdWidenOrShorten:
29342934
return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
29352935
case IrInstructionIdIntToPtr:
@@ -4200,7 +4200,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42004200

42014201
return ir_build_panic(irb, scope, node, arg0_value);
42024202
}
4203-
case BuiltinFnIdBitCast:
4203+
case BuiltinFnIdPtrCast:
42044204
{
42054205
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
42064206
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
@@ -4212,7 +4212,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42124212
if (arg1_value == irb->codegen->invalid_instruction)
42134213
return arg1_value;
42144214

4215-
return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4215+
return ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value);
42164216
}
42174217
}
42184218
zig_unreachable();
@@ -12182,34 +12182,36 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
1218212182
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
1218312183
}
1218412184

12185-
static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
12185+
static bool is_ptr_type(TypeTableEntry *t) {
12186+
return (t->id == TypeTableEntryIdPointer || t->id == TypeTableEntryIdFn ||
12187+
(t->id == TypeTableEntryIdMaybe && (t->data.maybe.child_type->id == TypeTableEntryIdPointer ||
12188+
t->data.maybe.child_type->id == TypeTableEntryIdFn)));
12189+
}
12190+
12191+
static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCast *instruction) {
1218612192
IrInstruction *dest_type_value = instruction->dest_type->other;
1218712193
TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
1218812194
if (type_is_invalid(dest_type))
1218912195
return ira->codegen->builtin_types.entry_invalid;
1219012196

12191-
IrInstruction *target = instruction->target->other;
12192-
TypeTableEntry *src_type = target->value.type;
12197+
IrInstruction *ptr = instruction->ptr->other;
12198+
TypeTableEntry *src_type = ptr->value.type;
1219312199
if (type_is_invalid(src_type))
1219412200
return ira->codegen->builtin_types.entry_invalid;
1219512201

12196-
ensure_complete_type(ira->codegen, dest_type);
12197-
ensure_complete_type(ira->codegen, src_type);
12202+
if (!is_ptr_type(src_type)) {
12203+
ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name)));
12204+
return ira->codegen->builtin_types.entry_invalid;
12205+
}
1219812206

12199-
uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);
12200-
uint64_t src_size_bytes = type_size(ira->codegen, src_type);
12201-
if (dest_size_bytes != src_size_bytes) {
12202-
ir_add_error(ira, &instruction->base,
12203-
buf_sprintf("destination type '%s' has size %" PRIu64 " but source type '%s' has size %" PRIu64,
12204-
buf_ptr(&dest_type->name), dest_size_bytes,
12205-
buf_ptr(&src_type->name), src_size_bytes));
12207+
if (!is_ptr_type(dest_type)) {
12208+
ir_add_error(ira, dest_type_value,
12209+
buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name)));
1220612210
return ira->codegen->builtin_types.entry_invalid;
1220712211
}
1220812212

12209-
if (instr_is_comptime(target) && src_type->id == dest_type->id &&
12210-
(src_type->id == TypeTableEntryIdPointer || src_type->id == TypeTableEntryIdMaybe))
12211-
{
12212-
ConstExprValue *val = ir_resolve_const(ira, target, UndefOk);
12213+
if (instr_is_comptime(ptr)) {
12214+
ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
1221312215
if (!val)
1221412216
return ira->codegen->builtin_types.entry_invalid;
1221512217

@@ -12219,8 +12221,8 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
1221912221
return dest_type;
1222012222
}
1222112223

12222-
IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope,
12223-
instruction->base.source_node, nullptr, target);
12224+
IrInstruction *result = ir_build_ptr_cast(&ira->new_irb, instruction->base.scope,
12225+
instruction->base.source_node, nullptr, ptr);
1222412226
ir_link_new_instruction(result, &instruction->base);
1222512227
result->value.type = dest_type;
1222612228
return dest_type;
@@ -12464,8 +12466,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1246412466
return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
1246512467
case IrInstructionIdPanic:
1246612468
return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
12467-
case IrInstructionIdBitCast:
12468-
return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
12469+
case IrInstructionIdPtrCast:
12470+
return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction);
1246912471
case IrInstructionIdMaybeWrap:
1247012472
case IrInstructionIdErrWrapCode:
1247112473
case IrInstructionIdErrWrapPayload:
@@ -12637,7 +12639,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1263712639
case IrInstructionIdFnProto:
1263812640
case IrInstructionIdTestComptime:
1263912641
case IrInstructionIdInitEnum:
12640-
case IrInstructionIdBitCast:
12642+
case IrInstructionIdPtrCast:
1264112643
case IrInstructionIdWidenOrShorten:
1264212644
case IrInstructionIdPtrToInt:
1264312645
case IrInstructionIdIntToPtr:

src/ir_print.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -765,9 +765,13 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction)
765765
fprintf(irp->f, "}");
766766
}
767767

768-
static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {
769-
fprintf(irp->f, "@bitcast(");
770-
ir_print_other_instruction(irp, instruction->target);
768+
static void ir_print_ptr_cast(IrPrint *irp, IrInstructionPtrCast *instruction) {
769+
fprintf(irp->f, "@ptrcast(");
770+
if (instruction->dest_type) {
771+
ir_print_other_instruction(irp, instruction->dest_type);
772+
}
773+
fprintf(irp->f, ",");
774+
ir_print_other_instruction(irp, instruction->ptr);
771775
fprintf(irp->f, ")");
772776
}
773777

@@ -1098,8 +1102,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
10981102
case IrInstructionIdInitEnum:
10991103
ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction);
11001104
break;
1101-
case IrInstructionIdBitCast:
1102-
ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);
1105+
case IrInstructionIdPtrCast:
1106+
ir_print_ptr_cast(irp, (IrInstructionPtrCast *)instruction);
11031107
break;
11041108
case IrInstructionIdWidenOrShorten:
11051109
ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);

std/debug.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
7474
const name = %return compile_unit.die.getAttrString(st, DW.AT_name);
7575

7676
%return out_stream.printf("{} -> {}\n", return_address, name);
77-
maybe_fp = *@bitcast(&const ?&const u8, fp);
77+
maybe_fp = *@ptrcast(&const ?&const u8, fp);
7878
}
7979
},
8080
ObjectFormat.coff => {

std/hash_map.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ test "basicHashMapTest" {
236236
}
237237

238238
fn hash_i32(x: i32) -> u32 {
239-
*@bitcast(&u32, &x)
239+
*@ptrcast(&u32, &x)
240240
}
241241
fn eql_i32(a: i32, b: i32) -> bool {
242242
a == b

std/mem.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub const IncrementingAllocator = struct {
7878
fn alloc(allocator: &Allocator, n: usize) -> %[]u8 {
7979
// TODO
8080
//const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
81-
const self = @bitcast(&IncrementingAllocator, allocator);
81+
const self = @ptrcast(&IncrementingAllocator, allocator);
8282
const new_end_index = self.end_index + n;
8383
if (new_end_index > self.bytes.len) {
8484
return error.NoMem;

std/os/linux.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ pub const AF_MAX = PF_MAX;
239239

240240
/// Get the errno from a syscall return value, or 0 for no error.
241241
pub fn getErrno(r: usize) -> usize {
242-
const signed_r = *@bitcast(&isize, &r);
242+
const signed_r = *@ptrcast(&isize, &r);
243243
if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
244244
}
245245

std/special/compiler_rt.zig

+12-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int {
1515

1616
fn du_int_to_udwords(x: du_int) -> udwords {
1717
@setDebugSafety(this, false);
18-
return *@bitcast(&udwords, &x);
18+
return *@ptrcast(&udwords, &x);
1919
}
2020

2121
export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
@@ -66,7 +66,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
6666
if (var rem ?= maybe_rem) {
6767
r[high] = n[high] % d[high];
6868
r[low] = 0;
69-
*rem = *@bitcast(&du_int, &r[0]);
69+
*rem = *@ptrcast(&du_int, &r[0]);
7070
}
7171
return n[high] / d[high];
7272
}
@@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
7878
if (var rem ?= maybe_rem) {
7979
r[low] = n[low];
8080
r[high] = n[high] & (d[high] - 1);
81-
*rem = *@bitcast(&du_int, &r[0]);
81+
*rem = *@ptrcast(&du_int, &r[0]);
8282
}
8383
return n[high] >> @ctz(d[high]);
8484
}
@@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
8989
// 0 <= sr <= n_uword_bits - 2 or sr large
9090
if (sr > n_uword_bits - 2) {
9191
if (var rem ?= maybe_rem) {
92-
*rem = *@bitcast(&du_int, &n[0]);
92+
*rem = *@ptrcast(&du_int, &n[0]);
9393
}
9494
return 0;
9595
}
@@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
113113
*rem = n[low] & (d[low] - 1);
114114
}
115115
if (d[low] == 1) {
116-
return *@bitcast(&du_int, &n[0]);
116+
return *@ptrcast(&du_int, &n[0]);
117117
}
118118
sr = @ctz(d[low]);
119119
q[high] = n[high] >> sr;
120120
q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
121-
return *@bitcast(&du_int, &q[0]);
121+
return *@ptrcast(&du_int, &q[0]);
122122
}
123123
// K X
124124
// ---
@@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
154154
// 0 <= sr <= n_uword_bits - 1 or sr large
155155
if (sr > n_uword_bits - 1) {
156156
if (var rem ?= maybe_rem) {
157-
*rem = *@bitcast(&du_int, &n[0]);
157+
*rem = *@ptrcast(&du_int, &n[0]);
158158
}
159159
return 0;
160160
}
@@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
191191
// r.all -= d.all;
192192
// carry = 1;
193193
// }
194-
const s: di_int = (di_int)(*@bitcast(&du_int, &d[0]) - *@bitcast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1);
194+
const s: di_int = (di_int)(*@ptrcast(&du_int, &d[0]) - *@ptrcast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1);
195195
carry = su_int(s & 1);
196-
*@bitcast(&du_int, &r[0]) -= *@bitcast(&du_int, &d[0]) & u64(s);
196+
*@ptrcast(&du_int, &r[0]) -= *@ptrcast(&du_int, &d[0]) & u64(s);
197197

198198
sr -= 1;
199199
}
200-
*@bitcast(&du_int, &q[0]) = (*@bitcast(&du_int, &q[0]) << 1) | u64(carry);
200+
*@ptrcast(&du_int, &q[0]) = (*@ptrcast(&du_int, &q[0]) << 1) | u64(carry);
201201
if (var rem ?= maybe_rem) {
202-
*rem = *@bitcast(&du_int, &r[0]);
202+
*rem = *@ptrcast(&du_int, &r[0]);
203203
}
204-
return *@bitcast(&du_int, &q[0]);
204+
return *@ptrcast(&du_int, &q[0]);
205205
}
206206

207207
export fn __umoddi3(a: du_int, b: du_int) -> du_int {

test/cases/cast.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ test "numLitIntToPtrCast" {
1515
test "pointerReinterpretConstFloatToInt" {
1616
const float: f64 = 5.99999999999994648725e-01;
1717
const float_ptr = &float;
18-
const int_ptr = @bitcast(&i32, float_ptr);
18+
const int_ptr = @ptrcast(&i32, float_ptr);
1919
const int_val = *int_ptr;
2020
assert(int_val == 858993411);
2121
}

0 commit comments

Comments
 (0)