@@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
480
480
return IrInstructionIdInitEnum;
481
481
}
482
482
483
- static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpret *) {
484
- return IrInstructionIdPointerReinterpret ;
483
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
484
+ return IrInstructionIdBitCast ;
485
485
}
486
486
487
487
static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
@@ -1940,14 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old
1940
1940
return new_instruction;
1941
1941
}
1942
1942
1943
- static IrInstruction *ir_build_pointer_reinterpret (IrBuilder *irb, Scope *scope, AstNode *source_node,
1944
- IrInstruction *ptr )
1943
+ static IrInstruction *ir_build_bit_cast (IrBuilder *irb, Scope *scope, AstNode *source_node,
1944
+ IrInstruction *dest_type, IrInstruction *target )
1945
1945
{
1946
- IrInstructionPointerReinterpret *instruction = ir_build_instruction<IrInstructionPointerReinterpret >(
1946
+ IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast >(
1947
1947
irb, scope, source_node);
1948
- instruction->ptr = ptr;
1948
+ instruction->dest_type = dest_type;
1949
+ instruction->target = target;
1949
1950
1950
- ir_ref_instruction(ptr, 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);
1951
1953
1952
1954
return &instruction->base;
1953
1955
}
@@ -2664,11 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins
2664
2666
}
2665
2667
}
2666
2668
2667
- static IrInstruction *ir_instruction_pointerreinterpret_get_dep(IrInstructionPointerReinterpret *instruction,
2669
+ static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
2668
2670
size_t index)
2669
2671
{
2670
2672
switch (index) {
2671
- case 0: return instruction->ptr;
2673
+ case 0: return instruction->dest_type;
2674
+ case 1: return instruction->target;
2672
2675
default: return nullptr;
2673
2676
}
2674
2677
}
@@ -2925,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
2925
2928
return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
2926
2929
case IrInstructionIdInitEnum:
2927
2930
return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
2928
- case IrInstructionIdPointerReinterpret :
2929
- return ir_instruction_pointerreinterpret_get_dep((IrInstructionPointerReinterpret *) instruction, index);
2931
+ case IrInstructionIdBitCast :
2932
+ return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
2930
2933
case IrInstructionIdWidenOrShorten:
2931
2934
return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
2932
2935
case IrInstructionIdIntToPtr:
@@ -4197,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4197
4200
4198
4201
return ir_build_panic(irb, scope, node, arg0_value);
4199
4202
}
4203
+ case BuiltinFnIdBitCast:
4204
+ {
4205
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4206
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4207
+ if (arg0_value == irb->codegen->invalid_instruction)
4208
+ return arg0_value;
4209
+
4210
+ AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4211
+ IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4212
+ if (arg1_value == irb->codegen->invalid_instruction)
4213
+ return arg1_value;
4214
+
4215
+ return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4216
+ }
4200
4217
}
4201
4218
zig_unreachable();
4202
4219
}
@@ -6364,34 +6381,6 @@ static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *sourc
6364
6381
return result;
6365
6382
}
6366
6383
6367
- static IrInstruction *ir_analyze_pointer_reinterpret(IrAnalyze *ira, IrInstruction *source_instr,
6368
- IrInstruction *ptr, TypeTableEntry *wanted_type)
6369
- {
6370
- if (ptr->value.type->id != TypeTableEntryIdPointer &&
6371
- ptr->value.type->id != TypeTableEntryIdMaybe)
6372
- {
6373
- ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&ptr->value.type->name)));
6374
- return ira->codegen->invalid_instruction;
6375
- }
6376
-
6377
- if (instr_is_comptime(ptr)) {
6378
- ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
6379
- if (!val)
6380
- return ira->codegen->invalid_instruction;
6381
-
6382
- IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
6383
- source_instr->scope, source_instr->source_node);
6384
- const_instruction->base.value = *val;
6385
- const_instruction->base.value.type = wanted_type;
6386
- return &const_instruction->base;
6387
- }
6388
-
6389
- IrInstruction *result = ir_build_pointer_reinterpret(&ira->new_irb, source_instr->scope,
6390
- source_instr->source_node, ptr);
6391
- result->value.type = wanted_type;
6392
- return result;
6393
- }
6394
-
6395
6384
static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
6396
6385
IrInstruction *value, TypeTableEntry *wanted_type)
6397
6386
{
@@ -6829,24 +6818,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
6829
6818
}
6830
6819
}
6831
6820
6832
- // explicit cast from pointer to another pointer
6833
- if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&
6834
- (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))
6835
- {
6836
- return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type);
6837
- }
6838
-
6839
- // explicit cast from maybe pointer to another maybe pointer
6840
- if (actual_type->id == TypeTableEntryIdMaybe &&
6841
- (actual_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
6842
- actual_type->data.maybe.child_type->id == TypeTableEntryIdFn) &&
6843
- wanted_type->id == TypeTableEntryIdMaybe &&
6844
- (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
6845
- wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))
6846
- {
6847
- return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type);
6848
- }
6849
-
6850
6821
// explicit cast from child type of maybe type to maybe type
6851
6822
if (wanted_type->id == TypeTableEntryIdMaybe) {
6852
6823
if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
@@ -8986,6 +8957,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
8986
8957
8987
8958
ConstExprValue *array_ptr_val;
8988
8959
if (array_ptr->value.special != ConstValSpecialRuntime &&
8960
+ array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar &&
8989
8961
(array_ptr_val = const_ptr_pointee(&array_ptr->value)) &&
8990
8962
array_ptr_val->special != ConstValSpecialRuntime &&
8991
8963
(array_type->id != TypeTableEntryIdPointer ||
@@ -12210,6 +12182,50 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
12210
12182
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
12211
12183
}
12212
12184
12185
+ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
12186
+ IrInstruction *dest_type_value = instruction->dest_type->other;
12187
+ TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
12188
+ if (type_is_invalid(dest_type))
12189
+ return ira->codegen->builtin_types.entry_invalid;
12190
+
12191
+ IrInstruction *target = instruction->target->other;
12192
+ TypeTableEntry *src_type = target->value.type;
12193
+ if (type_is_invalid(src_type))
12194
+ return ira->codegen->builtin_types.entry_invalid;
12195
+
12196
+ ensure_complete_type(ira->codegen, dest_type);
12197
+ ensure_complete_type(ira->codegen, src_type);
12198
+
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));
12206
+ return ira->codegen->builtin_types.entry_invalid;
12207
+ }
12208
+
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 (!val)
12214
+ return ira->codegen->builtin_types.entry_invalid;
12215
+
12216
+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
12217
+ *out_val = *val;
12218
+ out_val->type = dest_type;
12219
+ return dest_type;
12220
+ }
12221
+
12222
+ IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope,
12223
+ instruction->base.source_node, nullptr, target);
12224
+ ir_link_new_instruction(result, &instruction->base);
12225
+ result->value.type = dest_type;
12226
+ return dest_type;
12227
+ }
12228
+
12213
12229
static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
12214
12230
IrInstructionDeclRef *instruction)
12215
12231
{
@@ -12283,7 +12299,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
12283
12299
static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
12284
12300
switch (instruction->id) {
12285
12301
case IrInstructionIdInvalid:
12286
- case IrInstructionIdPointerReinterpret:
12287
12302
case IrInstructionIdWidenOrShorten:
12288
12303
case IrInstructionIdIntToPtr:
12289
12304
case IrInstructionIdPtrToInt:
@@ -12449,6 +12464,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
12449
12464
return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
12450
12465
case IrInstructionIdPanic:
12451
12466
return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
12467
+ case IrInstructionIdBitCast:
12468
+ return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
12452
12469
case IrInstructionIdMaybeWrap:
12453
12470
case IrInstructionIdErrWrapCode:
12454
12471
case IrInstructionIdErrWrapPayload:
@@ -12620,7 +12637,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
12620
12637
case IrInstructionIdFnProto:
12621
12638
case IrInstructionIdTestComptime:
12622
12639
case IrInstructionIdInitEnum:
12623
- case IrInstructionIdPointerReinterpret :
12640
+ case IrInstructionIdBitCast :
12624
12641
case IrInstructionIdWidenOrShorten:
12625
12642
case IrInstructionIdPtrToInt:
12626
12643
case IrInstructionIdIntToPtr:
0 commit comments