authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-07 23:45:54+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-11-18 13:21:36+02:00
log129ccad43443f26f00584816b18425c9a3a7b080
tree0c1e70c1f297163761c3850058feeba6cf7c7b60
parent252924ae33cbdd65ef0bc5d878a2dad57fb1ada6

stage1: Reject undefined values when taking union ptr

The code rightfully assumes the union_val object to be fully initialized. Closes #7019

2 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
2271322713 if (type_is_invalid(union_val->type))
2271422714 return ira->codegen->invalid_inst_gen;
2271522715
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
2271622726 if (initializing) {
2271722727 ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>();
2271822728 payload_val->special = ConstValSpecialUndef;
......@@ -22737,6 +22747,7 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name
2273722747 }
2273822748
2273922749 ZigValue *payload_val = union_val->data.x_union.payload;
22750 assert(payload_val);
2274022751
2274122752 IrInstGen *result;
2274222753 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
test/compile_errors.zig+15
......@@ -11,6 +11,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1111 "tmp.zig:1:50: error: use of undefined value here causes undefined behavior",
1212 });
1313
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
1429 cases.add("union with too small explicit signed tag type",
1530 \\const U = union(enum(i2)) {
1631 \\ A: u8,