| ... | @@ -810,6 +810,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { | ... | @@ -810,6 +810,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { |
| 810 | return buf_create_from_str("invalid error code"); | 810 | return buf_create_from_str("invalid error code"); |
| 811 | case PanicMsgIdIncorrectAlignment: | 811 | case PanicMsgIdIncorrectAlignment: |
| 812 | return buf_create_from_str("incorrect alignment"); | 812 | return buf_create_from_str("incorrect alignment"); |
| | 813 | case PanicMsgIdBadUnionField: |
| | 814 | return buf_create_from_str("access of inactive union field"); |
| 813 | } | 815 | } |
| 814 | zig_unreachable(); | 816 | zig_unreachable(); |
| 815 | } | 817 | } |
| ... | @@ -2415,6 +2417,23 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab | ... | @@ -2415,6 +2417,23 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab |
| 2415 | return bitcasted_union_field_ptr; | 2417 | return bitcasted_union_field_ptr; |
| 2416 | } | 2418 | } |
| 2417 | | 2419 | |
| | 2420 | if (ir_want_debug_safety(g, &instruction->base)) { |
| | 2421 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, ""); |
| | 2422 | LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, ""); |
| | 2423 | LLVMValueRef expected_tag_value = LLVMConstInt(union_type->data.unionation.tag_type->type_ref, |
| | 2424 | field->value, false); |
| | 2425 | |
| | 2426 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnionCheckOk"); |
| | 2427 | LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnionCheckFail"); |
| | 2428 | LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, tag_value, expected_tag_value, ""); |
| | 2429 | LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block); |
| | 2430 | |
| | 2431 | LLVMPositionBuilderAtEnd(g->builder, bad_block); |
| | 2432 | gen_debug_safety_crash(g, PanicMsgIdBadUnionField); |
| | 2433 | |
| | 2434 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| | 2435 | } |
| | 2436 | |
| 2418 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_union_index, ""); | 2437 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_union_index, ""); |
| 2419 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); | 2438 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); |
| 2420 | return bitcasted_union_field_ptr; | 2439 | return bitcasted_union_field_ptr; |
| ... | @@ -3977,21 +3996,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3977,21 +3996,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3977 | | 3996 | |
| 3978 | LLVMValueRef union_value_ref; | 3997 | LLVMValueRef union_value_ref; |
| 3979 | { | 3998 | { |
| 3980 | unsigned field_count; | | |
| 3981 | LLVMValueRef fields[2]; | | |
| 3982 | fields[0] = correctly_typed_value; | | |
| 3983 | if (pad_bytes == 0) { | 3999 | if (pad_bytes == 0) { |
| 3984 | field_count = 1; | 4000 | union_value_ref = correctly_typed_value; |
| 3985 | } else { | 4001 | } else { |
| | 4002 | LLVMValueRef fields[2]; |
| 3986 | fields[0] = correctly_typed_value; | 4003 | fields[0] = correctly_typed_value; |
| 3987 | fields[1] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), (unsigned)pad_bytes)); | 4004 | fields[1] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), (unsigned)pad_bytes)); |
| 3988 | field_count = 2; | 4005 | if (make_unnamed_struct || type_entry->data.unionation.gen_tag_index != SIZE_MAX) { |
| 3989 | } | 4006 | union_value_ref = LLVMConstStruct(fields, 2, false); |
| 3990 | | 4007 | } else { |
| 3991 | if (make_unnamed_struct || type_entry->data.unionation.gen_tag_index != SIZE_MAX) { | 4008 | union_value_ref = LLVMConstNamedStruct(union_type_ref, fields, 2); |
| 3992 | union_value_ref = LLVMConstStruct(fields, field_count, false); | 4009 | } |
| 3993 | } else { | | |
| 3994 | union_value_ref = LLVMConstNamedStruct(union_type_ref, fields, field_count); | | |
| 3995 | } | 4010 | } |
| 3996 | } | 4011 | } |
| 3997 | | 4012 | |