| author | |
| committer | |
| log | f8e63c458478022813a67bfd5ee64bfad6eee82e |
| tree | 52952d63618068cbe76ee1175623e7f9e2976de2 |
| parent | 3ca027ca8219dbdbb6467645944c4daada037f51 |
See #29015 files changed, 90 insertions(+), 81 deletions(-)
doc/langref.md+2-5| ... | @@ -634,9 +634,6 @@ calls the public `panic` function exposed in the root source file, or | ... | @@ -634,9 +634,6 @@ calls the public `panic` function exposed in the root source file, or |
| 634 | if there is not one specified, invokes the one provided in | 634 | if there is not one specified, invokes the one provided in |
| 635 | `std/special/panic.zig`. | 635 | `std/special/panic.zig`. |
| 636 | 636 | ||
| 637 | ### @bitcast(comptime DestType: type, value: var) -> DestType | 637 | ### @ptrcast(comptime DestType: type, value: var) -> DestType |
| 638 | 638 | ||
| 639 | Transmutes memory from one type to another without changing any bits. | 639 | Converts a pointer of one type to a pointer of another type. |
| 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`. |
src/all_types.hpp+4-4| ... | @@ -1196,7 +1196,7 @@ enum BuiltinFnId { | ... | @@ -1196,7 +1196,7 @@ enum BuiltinFnId { |
| 1196 | BuiltinFnIdSetGlobalSection, | 1196 | BuiltinFnIdSetGlobalSection, |
| 1197 | BuiltinFnIdSetGlobalLinkage, | 1197 | BuiltinFnIdSetGlobalLinkage, |
| 1198 | BuiltinFnIdPanic, | 1198 | BuiltinFnIdPanic, |
| 1199 | BuiltinFnIdBitCast, | 1199 | BuiltinFnIdPtrCast, |
| 1200 | }; | 1200 | }; |
| 1201 | 1201 | ||
| 1202 | struct BuiltinFnEntry { | 1202 | struct BuiltinFnEntry { |
| ... | @@ -1720,7 +1720,7 @@ enum IrInstructionId { | ... | @@ -1720,7 +1720,7 @@ enum IrInstructionId { |
| 1720 | IrInstructionIdFnProto, | 1720 | IrInstructionIdFnProto, |
| 1721 | IrInstructionIdTestComptime, | 1721 | IrInstructionIdTestComptime, |
| 1722 | IrInstructionIdInitEnum, | 1722 | IrInstructionIdInitEnum, |
| 1723 | IrInstructionIdBitCast, | 1723 | IrInstructionIdPtrCast, |
| 1724 | IrInstructionIdWidenOrShorten, | 1724 | IrInstructionIdWidenOrShorten, |
| 1725 | IrInstructionIdIntToPtr, | 1725 | IrInstructionIdIntToPtr, |
| 1726 | IrInstructionIdPtrToInt, | 1726 | IrInstructionIdPtrToInt, |
| ... | @@ -2370,11 +2370,11 @@ struct IrInstructionInitEnum { | ... | @@ -2370,11 +2370,11 @@ struct IrInstructionInitEnum { |
| 2370 | LLVMValueRef tmp_ptr; | 2370 | LLVMValueRef tmp_ptr; |
| 2371 | }; | 2371 | }; |
| 2372 | 2372 | ||
| 2373 | struct IrInstructionBitCast { | 2373 | struct IrInstructionPtrCast { |
| 2374 | IrInstruction base; | 2374 | IrInstruction base; |
| 2375 | 2375 | ||
| 2376 | IrInstruction *dest_type; | 2376 | IrInstruction *dest_type; |
| 2377 | IrInstruction *target; | 2377 | IrInstruction *ptr; |
| 2378 | }; | 2378 | }; |
| 2379 | 2379 | ||
| 2380 | struct IrInstructionWidenOrShorten { | 2380 | struct IrInstructionWidenOrShorten { |
src/codegen.cpp+7-7| ... | @@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, | ... | @@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, |
| 1345 | zig_unreachable(); | 1345 | zig_unreachable(); |
| 1346 | } | 1346 | } |
| 1347 | 1347 | ||
| 1348 | static LLVMValueRef ir_render_bitcast(CodeGen *g, IrExecutable *executable, | 1348 | static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable, |
| 1349 | IrInstructionBitCast *instruction) | 1349 | IrInstructionPtrCast *instruction) |
| 1350 | { | 1350 | { |
| 1351 | TypeTableEntry *wanted_type = instruction->base.value.type; | 1351 | TypeTableEntry *wanted_type = instruction->base.value.type; |
| 1352 | LLVMValueRef target = ir_llvm_value(g, instruction->target); | 1352 | LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); |
| 1353 | return LLVMBuildBitCast(g->builder, target, wanted_type->type_ref, ""); | 1353 | return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, ""); |
| 1354 | } | 1354 | } |
| 1355 | 1355 | ||
| 1356 | static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable, | 1356 | static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable, |
| ... | @@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2776 | return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction); | 2776 | return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction); |
| 2777 | case IrInstructionIdStructInit: | 2777 | case IrInstructionIdStructInit: |
| 2778 | return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction); | 2778 | return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction); |
| 2779 | case IrInstructionIdBitCast: | 2779 | case IrInstructionIdPtrCast: |
| 2780 | return ir_render_bitcast(g, executable, (IrInstructionBitCast *)instruction); | 2780 | return ir_render_ptr_cast(g, executable, (IrInstructionPtrCast *)instruction); |
| 2781 | case IrInstructionIdWidenOrShorten: | 2781 | case IrInstructionIdWidenOrShorten: |
| 2782 | return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction); | 2782 | return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction); |
| 2783 | case IrInstructionIdPtrToInt: | 2783 | case IrInstructionIdPtrToInt: |
| ... | @@ -4260,7 +4260,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -4260,7 +4260,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4260 | create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2); | 4260 | create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2); |
| 4261 | create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2); | 4261 | create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2); |
| 4262 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); | 4262 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); |
| 4263 | create_builtin_fn(g, BuiltinFnIdBitCast, "bitcast", 2); | 4263 | create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrcast", 2); |
| 4264 | } | 4264 | } |
| 4265 | 4265 | ||
| 4266 | static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) { | 4266 | static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) { |
src/ir.cpp+36-34| ... | @@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) { | ... | @@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) { |
| 480 | return IrInstructionIdInitEnum; | 480 | return IrInstructionIdInitEnum; |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { | 483 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCast *) { |
| 484 | return IrInstructionIdBitCast; | 484 | return IrInstructionIdPtrCast; |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { | 487 | static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { |
| ... | @@ -1940,16 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old | ... | @@ -1940,16 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old |
| 1940 | return new_instruction; | 1940 | return new_instruction; |
| 1941 | } | 1941 | } |
| 1942 | 1942 | ||
| 1943 | static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1943 | static IrInstruction *ir_build_ptr_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1944 | IrInstruction *dest_type, IrInstruction *target) | 1944 | IrInstruction *dest_type, IrInstruction *ptr) |
| 1945 | { | 1945 | { |
| 1946 | IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( | 1946 | IrInstructionPtrCast *instruction = ir_build_instruction<IrInstructionPtrCast>( |
| 1947 | irb, scope, source_node); | 1947 | irb, scope, source_node); |
| 1948 | instruction->dest_type = dest_type; | 1948 | instruction->dest_type = dest_type; |
| 1949 | instruction->target = target; | 1949 | instruction->ptr = ptr; |
| 1950 | 1950 | ||
| 1951 | if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); | 1951 | 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); |
| 1953 | 1953 | ||
| 1954 | return &instruction->base; | 1954 | return &instruction->base; |
| 1955 | } | 1955 | } |
| ... | @@ -2666,12 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins | ... | @@ -2666,12 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins |
| 2666 | } | 2666 | } |
| 2667 | } | 2667 | } |
| 2668 | 2668 | ||
| 2669 | static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction, | 2669 | static IrInstruction *ir_instruction_ptrcast_get_dep(IrInstructionPtrCast *instruction, |
| 2670 | size_t index) | 2670 | size_t index) |
| 2671 | { | 2671 | { |
| 2672 | switch (index) { | 2672 | switch (index) { |
| 2673 | case 0: return instruction->dest_type; | 2673 | case 0: return instruction->dest_type; |
| 2674 | case 1: return instruction->target; | 2674 | case 1: return instruction->ptr; |
| 2675 | default: return nullptr; | 2675 | default: return nullptr; |
| 2676 | } | 2676 | } |
| 2677 | } | 2677 | } |
| ... | @@ -2928,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -2928,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 2928 | return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index); | 2928 | return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index); |
| 2929 | case IrInstructionIdInitEnum: | 2929 | case IrInstructionIdInitEnum: |
| 2930 | return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index); | 2930 | return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index); |
| 2931 | case IrInstructionIdBitCast: | 2931 | case IrInstructionIdPtrCast: |
| 2932 | return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index); | 2932 | return ir_instruction_ptrcast_get_dep((IrInstructionPtrCast *) instruction, index); |
| 2933 | case IrInstructionIdWidenOrShorten: | 2933 | case IrInstructionIdWidenOrShorten: |
| 2934 | return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index); | 2934 | return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index); |
| 2935 | case IrInstructionIdIntToPtr: | 2935 | case IrInstructionIdIntToPtr: |
| ... | @@ -4200,7 +4200,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4200,7 +4200,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4200 | 4200 | ||
| 4201 | return ir_build_panic(irb, scope, node, arg0_value); | 4201 | return ir_build_panic(irb, scope, node, arg0_value); |
| 4202 | } | 4202 | } |
| 4203 | case BuiltinFnIdBitCast: | 4203 | case BuiltinFnIdPtrCast: |
| 4204 | { | 4204 | { |
| 4205 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4205 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4206 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | 4206 | 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 | ... | @@ -4212,7 +4212,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4212 | if (arg1_value == irb->codegen->invalid_instruction) | 4212 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4213 | return arg1_value; | 4213 | return arg1_value; |
| 4214 | 4214 | ||
| 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); |
| 4216 | } | 4216 | } |
| 4217 | } | 4217 | } |
| 4218 | zig_unreachable(); | 4218 | zig_unreachable(); |
| ... | @@ -12182,34 +12182,36 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio | ... | @@ -12182,34 +12182,36 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio |
| 12182 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); | 12182 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 12183 | } | 12183 | } |
| 12184 | 12184 | ||
| 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) { | ||
| 12186 | IrInstruction *dest_type_value = instruction->dest_type->other; | 12192 | IrInstruction *dest_type_value = instruction->dest_type->other; |
| 12187 | TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value); | 12193 | TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value); |
| 12188 | if (type_is_invalid(dest_type)) | 12194 | if (type_is_invalid(dest_type)) |
| 12189 | return ira->codegen->builtin_types.entry_invalid; | 12195 | return ira->codegen->builtin_types.entry_invalid; |
| 12190 | 12196 | ||
| 12191 | IrInstruction *target = instruction->target->other; | 12197 | IrInstruction *ptr = instruction->ptr->other; |
| 12192 | TypeTableEntry *src_type = target->value.type; | 12198 | TypeTableEntry *src_type = ptr->value.type; |
| 12193 | if (type_is_invalid(src_type)) | 12199 | if (type_is_invalid(src_type)) |
| 12194 | return ira->codegen->builtin_types.entry_invalid; | 12200 | return ira->codegen->builtin_types.entry_invalid; |
| 12195 | 12201 | ||
| 12196 | ensure_complete_type(ira->codegen, dest_type); | 12202 | if (!is_ptr_type(src_type)) { |
| 12197 | ensure_complete_type(ira->codegen, 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 | } | ||
| 12198 | 12206 | ||
| 12199 | uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); | 12207 | if (!is_ptr_type(dest_type)) { |
| 12200 | uint64_t src_size_bytes = type_size(ira->codegen, src_type); | 12208 | ir_add_error(ira, dest_type_value, |
| 12201 | if (dest_size_bytes != src_size_bytes) { | 12209 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); |
| 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)); | ||
| 12206 | return ira->codegen->builtin_types.entry_invalid; | 12210 | return ira->codegen->builtin_types.entry_invalid; |
| 12207 | } | 12211 | } |
| 12208 | 12212 | ||
| 12209 | if (instr_is_comptime(target) && src_type->id == dest_type->id && | 12213 | if (instr_is_comptime(ptr)) { |
| 12210 | (src_type->id == TypeTableEntryIdPointer || src_type->id == TypeTableEntryIdMaybe)) | 12214 | ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk); |
| 12211 | { | ||
| 12212 | ConstExprValue *val = ir_resolve_const(ira, target, UndefOk); | ||
| 12213 | if (!val) | 12215 | if (!val) |
| 12214 | return ira->codegen->builtin_types.entry_invalid; | 12216 | return ira->codegen->builtin_types.entry_invalid; |
| 12215 | 12217 | ||
| ... | @@ -12219,8 +12221,8 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc | ... | @@ -12219,8 +12221,8 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc |
| 12219 | return dest_type; | 12221 | return dest_type; |
| 12220 | } | 12222 | } |
| 12221 | 12223 | ||
| 12222 | IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope, | 12224 | IrInstruction *result = ir_build_ptr_cast(&ira->new_irb, instruction->base.scope, |
| 12223 | instruction->base.source_node, nullptr, target); | 12225 | instruction->base.source_node, nullptr, ptr); |
| 12224 | ir_link_new_instruction(result, &instruction->base); | 12226 | ir_link_new_instruction(result, &instruction->base); |
| 12225 | result->value.type = dest_type; | 12227 | result->value.type = dest_type; |
| 12226 | return dest_type; | 12228 | return dest_type; |
| ... | @@ -12464,8 +12466,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -12464,8 +12466,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 12464 | return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); | 12466 | return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); |
| 12465 | case IrInstructionIdPanic: | 12467 | case IrInstructionIdPanic: |
| 12466 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); | 12468 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); |
| 12467 | case IrInstructionIdBitCast: | 12469 | case IrInstructionIdPtrCast: |
| 12468 | return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); | 12470 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction); |
| 12469 | case IrInstructionIdMaybeWrap: | 12471 | case IrInstructionIdMaybeWrap: |
| 12470 | case IrInstructionIdErrWrapCode: | 12472 | case IrInstructionIdErrWrapCode: |
| 12471 | case IrInstructionIdErrWrapPayload: | 12473 | case IrInstructionIdErrWrapPayload: |
| ... | @@ -12637,7 +12639,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -12637,7 +12639,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 12637 | case IrInstructionIdFnProto: | 12639 | case IrInstructionIdFnProto: |
| 12638 | case IrInstructionIdTestComptime: | 12640 | case IrInstructionIdTestComptime: |
| 12639 | case IrInstructionIdInitEnum: | 12641 | case IrInstructionIdInitEnum: |
| 12640 | case IrInstructionIdBitCast: | 12642 | case IrInstructionIdPtrCast: |
| 12641 | case IrInstructionIdWidenOrShorten: | 12643 | case IrInstructionIdWidenOrShorten: |
| 12642 | case IrInstructionIdPtrToInt: | 12644 | case IrInstructionIdPtrToInt: |
| 12643 | case IrInstructionIdIntToPtr: | 12645 | case IrInstructionIdIntToPtr: |
src/ir_print.cpp+9-5| ... | @@ -765,9 +765,13 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction) | ... | @@ -765,9 +765,13 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction) |
| 765 | fprintf(irp->f, "}"); | 765 | fprintf(irp->f, "}"); |
| 766 | } | 766 | } |
| 767 | 767 | ||
| 768 | static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) { | 768 | static void ir_print_ptr_cast(IrPrint *irp, IrInstructionPtrCast *instruction) { |
| 769 | fprintf(irp->f, "@bitcast("); | 769 | fprintf(irp->f, "@ptrcast("); |
| 770 | ir_print_other_instruction(irp, instruction->target); | 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); | ||
| 771 | fprintf(irp->f, ")"); | 775 | fprintf(irp->f, ")"); |
| 772 | } | 776 | } |
| 773 | 777 | ||
| ... | @@ -1098,8 +1102,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1098,8 +1102,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1098 | case IrInstructionIdInitEnum: | 1102 | case IrInstructionIdInitEnum: |
| 1099 | ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction); | 1103 | ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction); |
| 1100 | break; | 1104 | break; |
| 1101 | case IrInstructionIdBitCast: | 1105 | case IrInstructionIdPtrCast: |
| 1102 | ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction); | 1106 | ir_print_ptr_cast(irp, (IrInstructionPtrCast *)instruction); |
| 1103 | break; | 1107 | break; |
| 1104 | case IrInstructionIdWidenOrShorten: | 1108 | case IrInstructionIdWidenOrShorten: |
| 1105 | ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction); | 1109 | ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction); |
std/debug.zig+1-1| ... | @@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void { | ... | @@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void { |
| 74 | const name = %return compile_unit.die.getAttrString(st, DW.AT_name); | 74 | const name = %return compile_unit.die.getAttrString(st, DW.AT_name); |
| 75 | 75 | ||
| 76 | %return out_stream.printf("{} -> {}\n", return_address, name); | 76 | %return out_stream.printf("{} -> {}\n", return_address, name); |
| 77 | maybe_fp = *@bitcast(&const ?&const u8, fp); | 77 | maybe_fp = *@ptrcast(&const ?&const u8, fp); |
| 78 | } | 78 | } |
| 79 | }, | 79 | }, |
| 80 | ObjectFormat.coff => { | 80 | ObjectFormat.coff => { |
std/hash_map.zig+1-1| ... | @@ -236,7 +236,7 @@ test "basicHashMapTest" { | ... | @@ -236,7 +236,7 @@ test "basicHashMapTest" { |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | fn hash_i32(x: i32) -> u32 { | 238 | fn hash_i32(x: i32) -> u32 { |
| 239 | *@bitcast(&u32, &x) | 239 | *@ptrcast(&u32, &x) |
| 240 | } | 240 | } |
| 241 | fn eql_i32(a: i32, b: i32) -> bool { | 241 | fn eql_i32(a: i32, b: i32) -> bool { |
| 242 | a == b | 242 | a == b |
std/mem.zig+1-1| ... | @@ -78,7 +78,7 @@ pub const IncrementingAllocator = struct { | ... | @@ -78,7 +78,7 @@ pub const IncrementingAllocator = struct { |
| 78 | fn alloc(allocator: &Allocator, n: usize) -> %[]u8 { | 78 | fn alloc(allocator: &Allocator, n: usize) -> %[]u8 { |
| 79 | // TODO | 79 | // TODO |
| 80 | //const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator); | 80 | //const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator); |
| 81 | const self = @bitcast(&IncrementingAllocator, allocator); | 81 | const self = @ptrcast(&IncrementingAllocator, allocator); |
| 82 | const new_end_index = self.end_index + n; | 82 | const new_end_index = self.end_index + n; |
| 83 | if (new_end_index > self.bytes.len) { | 83 | if (new_end_index > self.bytes.len) { |
| 84 | return error.NoMem; | 84 | return error.NoMem; |
std/os/linux.zig+1-1| ... | @@ -239,7 +239,7 @@ pub const AF_MAX = PF_MAX; | ... | @@ -239,7 +239,7 @@ pub const AF_MAX = PF_MAX; |
| 239 | 239 | ||
| 240 | /// Get the errno from a syscall return value, or 0 for no error. | 240 | /// Get the errno from a syscall return value, or 0 for no error. |
| 241 | pub fn getErrno(r: usize) -> usize { | 241 | pub fn getErrno(r: usize) -> usize { |
| 242 | const signed_r = *@bitcast(&isize, &r); | 242 | const signed_r = *@ptrcast(&isize, &r); |
| 243 | if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0 | 243 | if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0 |
| 244 | } | 244 | } |
| 245 | 245 |
std/special/compiler_rt.zig+12-12| ... | @@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int { | ... | @@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int { |
| 15 | 15 | ||
| 16 | fn du_int_to_udwords(x: du_int) -> udwords { | 16 | fn du_int_to_udwords(x: du_int) -> udwords { |
| 17 | @setDebugSafety(this, false); | 17 | @setDebugSafety(this, false); |
| 18 | return *@bitcast(&udwords, &x); | 18 | return *@ptrcast(&udwords, &x); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | 21 | 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 { | ... | @@ -66,7 +66,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 66 | if (var rem ?= maybe_rem) { | 66 | if (var rem ?= maybe_rem) { |
| 67 | r[high] = n[high] % d[high]; | 67 | r[high] = n[high] % d[high]; |
| 68 | r[low] = 0; | 68 | r[low] = 0; |
| 69 | *rem = *@bitcast(&du_int, &r[0]); | 69 | *rem = *@ptrcast(&du_int, &r[0]); |
| 70 | } | 70 | } |
| 71 | return n[high] / d[high]; | 71 | return n[high] / d[high]; |
| 72 | } | 72 | } |
| ... | @@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 78 | if (var rem ?= maybe_rem) { | 78 | if (var rem ?= maybe_rem) { |
| 79 | r[low] = n[low]; | 79 | r[low] = n[low]; |
| 80 | r[high] = n[high] & (d[high] - 1); | 80 | r[high] = n[high] & (d[high] - 1); |
| 81 | *rem = *@bitcast(&du_int, &r[0]); | 81 | *rem = *@ptrcast(&du_int, &r[0]); |
| 82 | } | 82 | } |
| 83 | return n[high] >> @ctz(d[high]); | 83 | return n[high] >> @ctz(d[high]); |
| 84 | } | 84 | } |
| ... | @@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 89 | // 0 <= sr <= n_uword_bits - 2 or sr large | 89 | // 0 <= sr <= n_uword_bits - 2 or sr large |
| 90 | if (sr > n_uword_bits - 2) { | 90 | if (sr > n_uword_bits - 2) { |
| 91 | if (var rem ?= maybe_rem) { | 91 | if (var rem ?= maybe_rem) { |
| 92 | *rem = *@bitcast(&du_int, &n[0]); | 92 | *rem = *@ptrcast(&du_int, &n[0]); |
| 93 | } | 93 | } |
| 94 | return 0; | 94 | return 0; |
| 95 | } | 95 | } |
| ... | @@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 113 | *rem = n[low] & (d[low] - 1); | 113 | *rem = n[low] & (d[low] - 1); |
| 114 | } | 114 | } |
| 115 | if (d[low] == 1) { | 115 | if (d[low] == 1) { |
| 116 | return *@bitcast(&du_int, &n[0]); | 116 | return *@ptrcast(&du_int, &n[0]); |
| 117 | } | 117 | } |
| 118 | sr = @ctz(d[low]); | 118 | sr = @ctz(d[low]); |
| 119 | q[high] = n[high] >> sr; | 119 | q[high] = n[high] >> sr; |
| 120 | q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr); | 120 | 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]); |
| 122 | } | 122 | } |
| 123 | // K X | 123 | // K X |
| 124 | // --- | 124 | // --- |
| ... | @@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 154 | // 0 <= sr <= n_uword_bits - 1 or sr large | 154 | // 0 <= sr <= n_uword_bits - 1 or sr large |
| 155 | if (sr > n_uword_bits - 1) { | 155 | if (sr > n_uword_bits - 1) { |
| 156 | if (var rem ?= maybe_rem) { | 156 | if (var rem ?= maybe_rem) { |
| 157 | *rem = *@bitcast(&du_int, &n[0]); | 157 | *rem = *@ptrcast(&du_int, &n[0]); |
| 158 | } | 158 | } |
| 159 | return 0; | 159 | return 0; |
| 160 | } | 160 | } |
| ... | @@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 191 | // r.all -= d.all; | 191 | // r.all -= d.all; |
| 192 | // carry = 1; | 192 | // carry = 1; |
| 193 | // } | 193 | // } |
| 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); |
| 195 | carry = su_int(s & 1); | 195 | 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); |
| 197 | 197 | ||
| 198 | sr -= 1; | 198 | sr -= 1; |
| 199 | } | 199 | } |
| 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); |
| 201 | if (var rem ?= maybe_rem) { | 201 | if (var rem ?= maybe_rem) { |
| 202 | *rem = *@bitcast(&du_int, &r[0]); | 202 | *rem = *@ptrcast(&du_int, &r[0]); |
| 203 | } | 203 | } |
| 204 | return *@bitcast(&du_int, &q[0]); | 204 | return *@ptrcast(&du_int, &q[0]); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | export fn __umoddi3(a: du_int, b: du_int) -> du_int { | 207 | export fn __umoddi3(a: du_int, b: du_int) -> du_int { |
test/cases/cast.zig+1-1| ... | @@ -15,7 +15,7 @@ test "numLitIntToPtrCast" { | ... | @@ -15,7 +15,7 @@ test "numLitIntToPtrCast" { |
| 15 | test "pointerReinterpretConstFloatToInt" { | 15 | test "pointerReinterpretConstFloatToInt" { |
| 16 | const float: f64 = 5.99999999999994648725e-01; | 16 | const float: f64 = 5.99999999999994648725e-01; |
| 17 | const float_ptr = &float; | 17 | const float_ptr = &float; |
| 18 | const int_ptr = @bitcast(&i32, float_ptr); | 18 | const int_ptr = @ptrcast(&i32, float_ptr); |
| 19 | const int_val = *int_ptr; | 19 | const int_val = *int_ptr; |
| 20 | assert(int_val == 858993411); | 20 | assert(int_val == 858993411); |
| 21 | } | 21 | } |
test/cases/generics.zig+1-1| ... | @@ -121,5 +121,5 @@ test "genericFnWithImplicitCast" { | ... | @@ -121,5 +121,5 @@ test "genericFnWithImplicitCast" { |
| 121 | } | 121 | } |
| 122 | fn getByte(ptr: ?&const u8) -> u8 {*??ptr} | 122 | fn getByte(ptr: ?&const u8) -> u8 {*??ptr} |
| 123 | fn getFirstByte(comptime T: type, mem: []const T) -> u8 { | 123 | fn getFirstByte(comptime T: type, mem: []const T) -> u8 { |
| 124 | getByte(@bitcast(&const u8, &mem[0])) | 124 | getByte(@ptrcast(&const u8, &mem[0])) |
| 125 | } | 125 | } |
test/cases/misc.zig+4-4| ... | @@ -246,15 +246,15 @@ test "typeEquality" { | ... | @@ -246,15 +246,15 @@ test "typeEquality" { |
| 246 | 246 | ||
| 247 | const global_a: i32 = 1234; | 247 | const global_a: i32 = 1234; |
| 248 | const global_b: &const i32 = &global_a; | 248 | const global_b: &const i32 = &global_a; |
| 249 | const global_c: &const f32 = @bitcast(&const f32, global_b); | 249 | const global_c: &const f32 = @ptrcast(&const f32, global_b); |
| 250 | test "compileTimeGlobalReinterpret" { | 250 | test "compileTimeGlobalReinterpret" { |
| 251 | const d = @bitcast(&const i32, global_c); | 251 | const d = @ptrcast(&const i32, global_c); |
| 252 | assert(*d == 1234); | 252 | assert(*d == 1234); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | test "explicitCastMaybePointers" { | 255 | test "explicitCastMaybePointers" { |
| 256 | const a: ?&i32 = undefined; | 256 | const a: ?&i32 = undefined; |
| 257 | const b: ?&f32 = @bitcast(?&f32, a); | 257 | const b: ?&f32 = @ptrcast(?&f32, a); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | test "genericMallocFree" { | 260 | test "genericMallocFree" { |
| ... | @@ -263,7 +263,7 @@ test "genericMallocFree" { | ... | @@ -263,7 +263,7 @@ test "genericMallocFree" { |
| 263 | } | 263 | } |
| 264 | const some_mem : [100]u8 = undefined; | 264 | const some_mem : [100]u8 = undefined; |
| 265 | fn memAlloc(comptime T: type, n: usize) -> %[]T { | 265 | fn memAlloc(comptime T: type, n: usize) -> %[]T { |
| 266 | return @bitcast(&T, &some_mem[0])[0...n]; | 266 | return @ptrcast(&T, &some_mem[0])[0...n]; |
| 267 | } | 267 | } |
| 268 | fn memFree(comptime T: type, memory: []T) { } | 268 | fn memFree(comptime T: type, memory: []T) { } |
| 269 | 269 |
test/cases/struct.zig+1-1| ... | @@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct { | ... | @@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct { |
| 41 | 41 | ||
| 42 | test "fn" { | 42 | test "fn" { |
| 43 | var foo: StructFoo = undefined; | 43 | var foo: StructFoo = undefined; |
| 44 | @memset(@bitcast(&u8, &foo), 0, @sizeOf(StructFoo)); | 44 | @memset(@ptrcast(&u8, &foo), 0, @sizeOf(StructFoo)); |
| 45 | foo.a += 1; | 45 | foo.a += 1; |
| 46 | foo.b = foo.a == 1; | 46 | foo.b = foo.a == 1; |
| 47 | testFoo(foo); | 47 | testFoo(foo); |
test/run_tests.cpp+9-3| ... | @@ -460,8 +460,8 @@ const foo : i32 = 0; | ... | @@ -460,8 +460,8 @@ const foo : i32 = 0; |
| 460 | const c = @cImport(@cInclude("stdlib.h")); | 460 | const c = @cImport(@cInclude("stdlib.h")); |
| 461 | 461 | ||
| 462 | export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { | 462 | export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { |
| 463 | const a_int = @bitcast(&i32, a ?? unreachable); | 463 | const a_int = @ptrcast(&i32, a ?? unreachable); |
| 464 | const b_int = @bitcast(&i32, b ?? unreachable); | 464 | const b_int = @ptrcast(&i32, b ?? unreachable); |
| 465 | if (*a_int < *b_int) { | 465 | if (*a_int < *b_int) { |
| 466 | -1 | 466 | -1 |
| 467 | } else if (*a_int > *b_int) { | 467 | } else if (*a_int > *b_int) { |
| ... | @@ -474,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { | ... | @@ -474,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { |
| 474 | export fn main(args: c_int, argv: &&u8) -> c_int { | 474 | export fn main(args: c_int, argv: &&u8) -> c_int { |
| 475 | var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; | 475 | var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; |
| 476 | 476 | ||
| 477 | c.qsort(@bitcast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn); | 477 | c.qsort(@ptrcast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn); |
| 478 | 478 | ||
| 479 | for (array) |item, i| { | 479 | for (array) |item, i| { |
| 480 | if (item != i) { | 480 | if (item != i) { |
| ... | @@ -1812,6 +1812,12 @@ export fn entry() { | ... | @@ -1812,6 +1812,12 @@ export fn entry() { |
| 1812 | foo(global_array); | 1812 | foo(global_array); |
| 1813 | } | 1813 | } |
| 1814 | )SOURCE", 1, ".tmp_source.zig:5:9: error: expected type '[]i32', found '[10]i32'"); | 1814 | )SOURCE", 1, ".tmp_source.zig:5:9: error: expected type '[]i32', found '[10]i32'"); |
| 1815 | |||
| 1816 | add_compile_fail_case("ptrcast to non-pointer", R"SOURCE( | ||
| 1817 | export fn entry(a: &i32) -> usize { | ||
| 1818 | return @ptrcast(usize, a); | ||
| 1819 | } | ||
| 1820 | )SOURCE", 1, ".tmp_source.zig:3:21: error: expected pointer, found 'usize'"); | ||
| 1815 | } | 1821 | } |
| 1816 | 1822 | ||
| 1817 | ////////////////////////////////////////////////////////////////////////////// | 1823 | ////////////////////////////////////////////////////////////////////////////// |