| author | |
| committer | |
| log | 129ccad43443f26f00584816b18425c9a3a7b080 |
| tree | 0c1e70c1f297163761c3850058feeba6cf7c7b60 |
| parent | 252924ae33cbdd65ef0bc5d878a2dad57fb1ada6 |
The code rightfully assumes the union_val object to be fully initialized.
Closes #70192 files changed, 26 insertions(+), 0 deletions(-)
src/stage1/ir.cpp+11| ... | ... | @@ -22713,6 +22713,16 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name |
| 22713 | 22713 | if (type_is_invalid(union_val->type)) |
| 22714 | 22714 | return ira->codegen->invalid_inst_gen; |
| 22715 | 22715 | |
| 22716 | // Reject undefined values unless we're intializing the union: | |
| 22717 | // a undefined union means also the tag is undefined, accessing | |
| 22718 | // its payload slot is UB. | |
| 22719 | const UndefAllowed allow_undef = initializing ? UndefOk : UndefBad; | |
| 22720 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, | |
| 22721 | source_instr->source_node, union_val, allow_undef))) | |
| 22722 | { | |
| 22723 | return ira->codegen->invalid_inst_gen; | |
| 22724 | } | |
| 22725 | ||
| 22716 | 22726 | if (initializing) { |
| 22717 | 22727 | ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>(); |
| 22718 | 22728 | payload_val->special = ConstValSpecialUndef; |
| ... | ... | @@ -22737,6 +22747,7 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name |
| 22737 | 22747 | } |
| 22738 | 22748 | |
| 22739 | 22749 | ZigValue *payload_val = union_val->data.x_union.payload; |
| 22750 | assert(payload_val); | |
| 22740 | 22751 | |
| 22741 | 22752 | IrInstGen *result; |
| 22742 | 22753 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
test/compile_errors.zig+15| ... | ... | @@ -11,6 +11,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 11 | 11 | "tmp.zig:1:50: error: use of undefined value here causes undefined behavior", |
| 12 | 12 | }); |
| 13 | 13 | |
| 14 | cases.add("wrong initializer for union payload of type 'type'", | |
| 15 | \\const U = union(enum) { | |
| 16 | \\ A: type, | |
| 17 | \\}; | |
| 18 | \\const S = struct { | |
| 19 | \\ u: U, | |
| 20 | \\}; | |
| 21 | \\export fn entry() void { | |
| 22 | \\ comptime var v: S = undefined; | |
| 23 | \\ v.u.A = U{ .A = i32 }; | |
| 24 | \\} | |
| 25 | , &[_][]const u8{ | |
| 26 | "tmp.zig:9:8: error: use of undefined value here causes undefined behavior", | |
| 27 | }); | |
| 28 | ||
| 14 | 29 | cases.add("union with too small explicit signed tag type", |
| 15 | 30 | \\const U = union(enum(i2)) { |
| 16 | 31 | \\ A: u8, |