authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-21 10:07:11-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-21 10:07:11-05:00
log2bb795dc455823e76ef3e0c9b3fcee6bcb15fddb
tree995e0a82e2d47d0b6701716372808ae7a40a406f
parentdb31c2524df4352593128aaceaa0b085ef8bb674
signaturelock-open Commit is signed but in an unrecognized format.

`@sliceToBytes` works at comptime

closes #262

6 files changed, 185 insertions(+), 84 deletions(-)

src/all_types.hpp+20-13
...@@ -630,19 +630,6 @@ struct AstNodeUnwrapOptional {...@@ -630,19 +630,6 @@ struct AstNodeUnwrapOptional {
630 AstNode *expr;630 AstNode *expr;
631};631};
632632
633enum CastOp {
634 CastOpNoCast, // signifies the function call expression is not a cast
635 CastOpNoop, // fn call expr is a cast, but does nothing
636 CastOpIntToFloat,
637 CastOpFloatToInt,
638 CastOpBoolToInt,
639 CastOpResizeSlice,
640 CastOpNumLitToConcrete,
641 CastOpErrSet,
642 CastOpBitCast,
643 CastOpPtrOfArrayToSlice,
644};
645
646struct AstNodeFnCallExpr {633struct AstNodeFnCallExpr {
647 AstNode *fn_ref_expr;634 AstNode *fn_ref_expr;
648 ZigList<AstNode *> params;635 ZigList<AstNode *> params;
...@@ -2142,6 +2129,7 @@ enum IrInstructionId {...@@ -2142,6 +2129,7 @@ enum IrInstructionId {
2142 IrInstructionIdConst,2129 IrInstructionIdConst,
2143 IrInstructionIdReturn,2130 IrInstructionIdReturn,
2144 IrInstructionIdCast,2131 IrInstructionIdCast,
2132 IrInstructionIdResizeSlice,
2145 IrInstructionIdContainerInitList,2133 IrInstructionIdContainerInitList,
2146 IrInstructionIdContainerInitFields,2134 IrInstructionIdContainerInitFields,
2147 IrInstructionIdStructInit,2135 IrInstructionIdStructInit,
...@@ -2503,6 +2491,18 @@ struct IrInstructionReturn {...@@ -2503,6 +2491,18 @@ struct IrInstructionReturn {
2503 IrInstruction *value;2491 IrInstruction *value;
2504};2492};
25052493
2494enum CastOp {
2495 CastOpNoCast, // signifies the function call expression is not a cast
2496 CastOpNoop, // fn call expr is a cast, but does nothing
2497 CastOpIntToFloat,
2498 CastOpFloatToInt,
2499 CastOpBoolToInt,
2500 CastOpNumLitToConcrete,
2501 CastOpErrSet,
2502 CastOpBitCast,
2503 CastOpPtrOfArrayToSlice,
2504};
2505
2506// TODO get rid of this instruction, replace with instructions for each op code2506// TODO get rid of this instruction, replace with instructions for each op code
2507struct IrInstructionCast {2507struct IrInstructionCast {
2508 IrInstruction base;2508 IrInstruction base;
...@@ -2513,6 +2513,13 @@ struct IrInstructionCast {...@@ -2513,6 +2513,13 @@ struct IrInstructionCast {
2513 LLVMValueRef tmp_ptr;2513 LLVMValueRef tmp_ptr;
2514};2514};
25152515
2516struct IrInstructionResizeSlice {
2517 IrInstruction base;
2518
2519 IrInstruction *operand;
2520 LLVMValueRef tmp_ptr;
2521};
2522
2516struct IrInstructionContainerInitList {2523struct IrInstructionContainerInitList {
2517 IrInstruction base;2524 IrInstruction base;
25182525
src/codegen.cpp+75-63
...@@ -2882,6 +2882,76 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in...@@ -2882,6 +2882,76 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in
2882 }2882 }
2883}2883}
28842884
2885static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
2886 IrInstructionResizeSlice *instruction)
2887{
2888 ZigType *actual_type = instruction->operand->value.type;
2889 ZigType *wanted_type = instruction->base.value.type;
2890 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
2891 assert(expr_val);
2892
2893 assert(instruction->tmp_ptr);
2894 assert(wanted_type->id == ZigTypeIdStruct);
2895 assert(wanted_type->data.structure.is_slice);
2896 assert(actual_type->id == ZigTypeIdStruct);
2897 assert(actual_type->data.structure.is_slice);
2898
2899 ZigType *actual_pointer_type = actual_type->data.structure.fields[0].type_entry;
2900 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;
2901 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
2902 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
2903
2904
2905 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index].gen_index;
2906 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index].gen_index;
2907 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index].gen_index;
2908 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index].gen_index;
2909
2910 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");
2911 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
2912 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
2913 wanted_type->data.structure.fields[0].type_entry->type_ref, "");
2914 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
2915 (unsigned)wanted_ptr_index, "");
2916 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
2917
2918 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, "");
2919 LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, "");
2920 uint64_t src_size = type_size(g, actual_child_type);
2921 uint64_t dest_size = type_size(g, wanted_child_type);
2922
2923 LLVMValueRef new_len;
2924 if (dest_size == 1) {
2925 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, src_size, false);
2926 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
2927 } else if (src_size == 1) {
2928 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);
2929 if (ir_want_runtime_safety(g, &instruction->base)) {
2930 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
2931 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
2932 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
2933 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk");
2934 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail");
2935 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
2936
2937 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2938 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
2939
2940 LLVMPositionBuilderAtEnd(g->builder, ok_block);
2941 }
2942 new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, "");
2943 } else {
2944 zig_unreachable();
2945 }
2946
2947 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
2948 (unsigned)wanted_len_index, "");
2949 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
2950
2951
2952 return instruction->tmp_ptr;
2953}
2954
2885static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,2955static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
2886 IrInstructionCast *cast_instruction)2956 IrInstructionCast *cast_instruction)
2887{2957{
...@@ -2896,69 +2966,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -2896,69 +2966,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
2896 zig_unreachable();2966 zig_unreachable();
2897 case CastOpNoop:2967 case CastOpNoop:
2898 return expr_val;2968 return expr_val;
2899 case CastOpResizeSlice:
2900 {
2901 assert(cast_instruction->tmp_ptr);
2902 assert(wanted_type->id == ZigTypeIdStruct);
2903 assert(wanted_type->data.structure.is_slice);
2904 assert(actual_type->id == ZigTypeIdStruct);
2905 assert(actual_type->data.structure.is_slice);
2906
2907 ZigType *actual_pointer_type = actual_type->data.structure.fields[0].type_entry;
2908 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;
2909 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
2910 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
2911
2912
2913 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index].gen_index;
2914 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index].gen_index;
2915 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index].gen_index;
2916 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index].gen_index;
2917
2918 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");
2919 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
2920 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
2921 wanted_type->data.structure.fields[0].type_entry->type_ref, "");
2922 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
2923 (unsigned)wanted_ptr_index, "");
2924 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
2925
2926 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, "");
2927 LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, "");
2928 uint64_t src_size = type_size(g, actual_child_type);
2929 uint64_t dest_size = type_size(g, wanted_child_type);
2930
2931 LLVMValueRef new_len;
2932 if (dest_size == 1) {
2933 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, src_size, false);
2934 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
2935 } else if (src_size == 1) {
2936 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);
2937 if (ir_want_runtime_safety(g, &cast_instruction->base)) {
2938 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
2939 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
2940 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
2941 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk");
2942 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail");
2943 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
2944
2945 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2946 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
2947
2948 LLVMPositionBuilderAtEnd(g->builder, ok_block);
2949 }
2950 new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, "");
2951 } else {
2952 zig_unreachable();
2953 }
2954
2955 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
2956 (unsigned)wanted_len_index, "");
2957 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
2958
2959
2960 return cast_instruction->tmp_ptr;
2961 }
2962 case CastOpIntToFloat:2969 case CastOpIntToFloat:
2963 assert(actual_type->id == ZigTypeIdInt);2970 assert(actual_type->id == ZigTypeIdInt);
2964 if (actual_type->data.integral.is_signed) {2971 if (actual_type->data.integral.is_signed) {
...@@ -5625,6 +5632,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5625,6 +5632,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5625 return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction);5632 return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction);
5626 case IrInstructionIdAssertZero:5633 case IrInstructionIdAssertZero:
5627 return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction);5634 return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction);
5635 case IrInstructionIdResizeSlice:
5636 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
5628 }5637 }
5629 zig_unreachable();5638 zig_unreachable();
5630}5639}
...@@ -6716,6 +6725,9 @@ static void do_code_gen(CodeGen *g) {...@@ -6716,6 +6725,9 @@ static void do_code_gen(CodeGen *g) {
6716 } else if (instruction->id == IrInstructionIdCmpxchgGen) {6725 } else if (instruction->id == IrInstructionIdCmpxchgGen) {
6717 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;6726 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
6718 slot = &cmpxchg_instruction->tmp_ptr;6727 slot = &cmpxchg_instruction->tmp_ptr;
6728 } else if (instruction->id == IrInstructionIdResizeSlice) {
6729 IrInstructionResizeSlice *resize_slice_instruction = (IrInstructionResizeSlice *)instruction;
6730 slot = &resize_slice_instruction->tmp_ptr;
6719 } else if (instruction->id == IrInstructionIdVectorToArray) {6731 } else if (instruction->id == IrInstructionIdVectorToArray) {
6720 IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;6732 IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
6721 alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);6733 alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
src/ir.cpp+51-8
...@@ -456,6 +456,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) {...@@ -456,6 +456,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) {
456 return IrInstructionIdCast;456 return IrInstructionIdCast;
457}457}
458458
459static constexpr IrInstructionId ir_instruction_id(IrInstructionResizeSlice *) {
460 return IrInstructionIdResizeSlice;
461}
462
459static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) {463static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) {
460 return IrInstructionIdContainerInitList;464 return IrInstructionIdContainerInitList;
461}465}
...@@ -1475,6 +1479,19 @@ static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *sourc...@@ -1475,6 +1479,19 @@ static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *sourc
1475 return &decl_var_instruction->base;1479 return &decl_var_instruction->base;
1476}1480}
14771481
1482static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction,
1483 IrInstruction *operand, ZigType *ty)
1484{
1485 IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb,
1486 source_instruction->scope, source_instruction->source_node);
1487 instruction->base.value.type = ty;
1488 instruction->operand = operand;
1489
1490 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1491
1492 return &instruction->base;
1493}
1494
1478static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node,1495static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node,
1479 IrInstruction *name, IrInstruction *target, IrInstruction *linkage)1496 IrInstruction *name, IrInstruction *target, IrInstruction *linkage)
1480{1497{
...@@ -9674,9 +9691,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_...@@ -9674,9 +9691,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
9674 }9691 }
9675 const_val->type = new_type;9692 const_val->type = new_type;
9676 break;9693 break;
9677 case CastOpResizeSlice:
9678 // can't do it
9679 zig_unreachable();
9680 case CastOpIntToFloat:9694 case CastOpIntToFloat:
9681 {9695 {
9682 assert(new_type->id == ZigTypeIdFloat);9696 assert(new_type->id == ZigTypeIdFloat);
...@@ -9740,9 +9754,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z...@@ -9740,9 +9754,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z
9740static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,9754static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
9741 ZigType *wanted_type, CastOp cast_op, bool need_alloca)9755 ZigType *wanted_type, CastOp cast_op, bool need_alloca)
9742{9756{
9743 if ((instr_is_comptime(value) || !type_has_bits(wanted_type)) &&9757 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) {
9744 cast_op != CastOpResizeSlice)
9745 {
9746 IrInstruction *result = ir_const(ira, source_instr, wanted_type);9758 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
9747 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, &value->value, value->value.type,9759 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, &value->value, value->value.type,
9748 &result->value, wanted_type))9760 &result->value, wanted_type))
...@@ -19082,7 +19094,9 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru...@@ -19082,7 +19094,9 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
19082 }19094 }
19083 }19095 }
1908419096
19085 return ir_resolve_cast(ira, &instruction->base, casted_value, dest_slice_type, CastOpResizeSlice, true);19097 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type);
19098 ir_add_alloca(ira, result, dest_slice_type);
19099 return result;
19086}19100}
1908719101
19088static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) {19102static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) {
...@@ -19109,7 +19123,34 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct...@@ -19109,7 +19123,34 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
19109 alignment, 0, 0);19123 alignment, 0, 0);
19110 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);19124 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
1911119125
19112 return ir_resolve_cast(ira, &instruction->base, target, dest_slice_type, CastOpResizeSlice, true);19126 if (instr_is_comptime(target)) {
19127 ConstExprValue *target_val = ir_resolve_const(ira, target, UndefBad);
19128 if (target_val == nullptr)
19129 return ira->codegen->invalid_instruction;
19130
19131 IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type);
19132 result->value.data.x_struct.fields = create_const_vals(2);
19133
19134 ConstExprValue *ptr_val = &result->value.data.x_struct.fields[slice_ptr_index];
19135 ConstExprValue *target_ptr_val = &target_val->data.x_struct.fields[slice_ptr_index];
19136 copy_const_val(ptr_val, target_ptr_val, false);
19137 ptr_val->type = dest_ptr_type;
19138
19139 ConstExprValue *len_val = &result->value.data.x_struct.fields[slice_len_index];
19140 len_val->special = ConstValSpecialStatic;
19141 len_val->type = ira->codegen->builtin_types.entry_usize;
19142 ConstExprValue *target_len_val = &target_val->data.x_struct.fields[slice_len_index];
19143 ZigType *elem_type = src_ptr_type->data.pointer.child_type;
19144 BigInt elem_size_bigint;
19145 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type));
19146 bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint);
19147
19148 return result;
19149 }
19150
19151 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type);
19152 ir_add_alloca(ira, result, dest_slice_type);
19153 return result;
19113}19154}
1911419155
19115static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {19156static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {
...@@ -22274,6 +22315,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -22274,6 +22315,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
22274 case IrInstructionIdArrayToVector:22315 case IrInstructionIdArrayToVector:
22275 case IrInstructionIdVectorToArray:22316 case IrInstructionIdVectorToArray:
22276 case IrInstructionIdAssertZero:22317 case IrInstructionIdAssertZero:
22318 case IrInstructionIdResizeSlice:
22277 zig_unreachable();22319 zig_unreachable();
2227822320
22279 case IrInstructionIdReturn:22321 case IrInstructionIdReturn:
...@@ -22673,6 +22715,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -22673,6 +22715,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
22673 case IrInstructionIdCmpxchgGen:22715 case IrInstructionIdCmpxchgGen:
22674 case IrInstructionIdCmpxchgSrc:22716 case IrInstructionIdCmpxchgSrc:
22675 case IrInstructionIdAssertZero:22717 case IrInstructionIdAssertZero:
22718 case IrInstructionIdResizeSlice:
22676 return true;22719 return true;
2267722720
22678 case IrInstructionIdPhi:22721 case IrInstructionIdPhi:
src/ir_print.cpp+9
...@@ -990,6 +990,12 @@ static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruct...@@ -990,6 +990,12 @@ static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruct
990 fprintf(irp->f, ")");990 fprintf(irp->f, ")");
991}991}
992992
993static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) {
994 fprintf(irp->f, "@resizeSlice(");
995 ir_print_other_instruction(irp, instruction->operand);
996 fprintf(irp->f, ")");
997}
998
993static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {999static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
994 fprintf(irp->f, "inttoerr ");1000 fprintf(irp->f, "inttoerr ");
995 ir_print_other_instruction(irp, instruction->target);1001 ir_print_other_instruction(irp, instruction->target);
...@@ -1852,6 +1858,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1852,6 +1858,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1852 case IrInstructionIdAssertZero:1858 case IrInstructionIdAssertZero:
1853 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);1859 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
1854 break;1860 break;
1861 case IrInstructionIdResizeSlice:
1862 ir_print_resize_slice(irp, (IrInstructionResizeSlice *)instruction);
1863 break;
1855 }1864 }
1856 fprintf(irp->f, "\n");1865 fprintf(irp->f, "\n");
1857}1866}
test/stage1/behavior.zig+1
...@@ -61,6 +61,7 @@ comptime {...@@ -61,6 +61,7 @@ comptime {
61 _ = @import("behavior/reflection.zig");61 _ = @import("behavior/reflection.zig");
62 _ = @import("behavior/sizeof_and_typeof.zig");62 _ = @import("behavior/sizeof_and_typeof.zig");
63 _ = @import("behavior/slice.zig");63 _ = @import("behavior/slice.zig");
64 _ = @import("behavior/slicetobytes.zig");
64 _ = @import("behavior/struct.zig");65 _ = @import("behavior/struct.zig");
65 _ = @import("behavior/struct_contains_null_ptr_itself.zig");66 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
66 _ = @import("behavior/struct_contains_slice_of_itself.zig");67 _ = @import("behavior/struct_contains_slice_of_itself.zig");
test/stage1/behavior/slicetobytes.zig created+29
...@@ -0,0 +1,29 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4
5test "@sliceToBytes packed struct at runtime and comptime" {
6 const Foo = packed struct {
7 a: u4,
8 b: u4,
9 };
10 const S = struct {
11 fn doTheTest() void {
12 var foo: Foo = undefined;
13 var slice = @sliceToBytes(((*[1]Foo)(&foo))[0..1]);
14 slice[0] = 0x13;
15 switch (builtin.endian) {
16 builtin.Endian.Big => {
17 expect(foo.a == 0x1);
18 expect(foo.b == 0x3);
19 },
20 builtin.Endian.Little => {
21 expect(foo.a == 0x3);
22 expect(foo.b == 0x1);
23 },
24 }
25 }
26 };
27 S.doTheTest();
28 comptime S.doTheTest();
29}