| ... | ... | @@ -810,6 +810,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { |
| 810 | 810 | return buf_create_from_str("invalid error code"); |
| 811 | 811 | case PanicMsgIdIncorrectAlignment: |
| 812 | 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 | 816 | zig_unreachable(); |
| 815 | 817 | } |
| ... | ... | @@ -2415,6 +2417,23 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab |
| 2415 | 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 | 2437 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_union_index, ""); |
| 2419 | 2438 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); |
| 2420 | 2439 | return bitcasted_union_field_ptr; |
| ... | ... | @@ -3977,21 +3996,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3977 | 3996 | |
| 3978 | 3997 | LLVMValueRef union_value_ref; |
| 3979 | 3998 | { |
| 3980 | | unsigned field_count; |
| 3981 | | LLVMValueRef fields[2]; |
| 3982 | | fields[0] = correctly_typed_value; |
| 3983 | 3999 | if (pad_bytes == 0) { |
| 3984 | | field_count = 1; |
| 4000 | union_value_ref = correctly_typed_value; |
| 3985 | 4001 | } else { |
| 4002 | LLVMValueRef fields[2]; |
| 3986 | 4003 | fields[0] = correctly_typed_value; |
| 3987 | 4004 | fields[1] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), (unsigned)pad_bytes)); |
| 3988 | | field_count = 2; |
| 3989 | | } |
| 3990 | | |
| 3991 | | if (make_unnamed_struct || type_entry->data.unionation.gen_tag_index != SIZE_MAX) { |
| 3992 | | union_value_ref = LLVMConstStruct(fields, field_count, false); |
| 3993 | | } else { |
| 3994 | | union_value_ref = LLVMConstNamedStruct(union_type_ref, fields, field_count); |
| 4005 | if (make_unnamed_struct || type_entry->data.unionation.gen_tag_index != SIZE_MAX) { |
| 4006 | union_value_ref = LLVMConstStruct(fields, 2, false); |
| 4007 | } else { |
| 4008 | union_value_ref = LLVMConstNamedStruct(union_type_ref, fields, 2); |
| 4009 | } |
| 3995 | 4010 | } |
| 3996 | 4011 | } |
| 3997 | 4012 | |