From 3464351d1e0a1e840d0b1a6267d0a5bf4113cfcc Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 10 Oct 2019 04:55:09 -0400 Subject: stage1: fix ir_resolve_str() to return slice `ir_resolve_str()` bug returns array expression even when when sliced to a lesser length. Fix is to return array if slice.len == array.len, otherwise return slice. Bug report use-case is based on one builtin function. However, at least the following builtins were exposed to the bug: `@byteOffsetOf` `@cDefine` `@cImport` `@cInclude` `@cUndef` `@compileError` `@embedFile` `@export` `@fieldParentPtr` `@hasDecl` `@hasField` `@import` `@unionInit` closes #3384 --- src/ir.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 0e6153ebcd..8fecbf7a18 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13122,7 +13122,6 @@ static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMod return true; } - static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { if (type_is_invalid(value->value.type)) return nullptr; @@ -13143,11 +13142,11 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; - if (array_val->data.x_array.special == ConstArraySpecialBuf) { - return array_val->data.x_array.data.s_buf; - } expand_undef_array(ira->codegen, array_val); size_t len = bigint_as_usize(&len_field->data.x_bigint); + if (array_val->data.x_array.special == ConstArraySpecialBuf && len == buf_len(array_val->data.x_array.data.s_buf)) { + return array_val->data.x_array.data.s_buf; + } Buf *result = buf_alloc(); buf_resize(result, len); for (size_t i = 0; i < len; i += 1) { -- cgit v1.2.3 From 6cbb732b59d1ded92c7272a8b06f645e1c8acfd2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 10 Oct 2019 10:47:59 +0200 Subject: Extern unions should not trigger active field check Fixes #3378 --- src/ir.cpp | 2 +- test/stage1/behavior/union.zig | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 8fecbf7a18..7dd141423c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17951,7 +17951,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ union_val->special = ConstValSpecialStatic; bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); union_val->data.x_union.payload = payload_val; - } else { + } else if (bare_type->data.unionation.layout != ContainerLayoutExtern) { TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); if (actual_field == nullptr) zig_unreachable(); diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index d340a52d1e..f5e9ec09a8 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -511,3 +511,13 @@ test "union with comptime_int tag" { }; comptime expect(@TagType(@TagType(Union)) == comptime_int); } + +test "extern union doesn't trigger field check at comptime" { + const U = extern union { + x: u32, + y: u8, + }; + + const x = U{ .x = 0x55AAAA55 }; + comptime expect(x.y == 0x55); +} -- cgit v1.2.3