From 3464351d1e0a1e840d0b1a6267d0a5bf4113cfcc Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 10 Oct 2019 04:55:09 -0400 Subject: [PATCH] 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 +++---- test/stage1/behavior.zig | 1 + test/stage1/behavior/bugs/3384.zig | 11 +++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 test/stage1/behavior/bugs/3384.zig diff --git a/src/ir.cpp b/src/ir.cpp index 0e6153ebcd66d6a51d4ffb0b7db5caa42e55790a..8fecbf7a187f046db46fa5cc120f87ded5d7bdb5 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) { diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index 95cb98f8eb4d65ef198665ddc179bf7aa6ea2527..95d2dbac93beaac5c741e429fd6481934fddd340 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -35,6 +35,7 @@ comptime { _ = @import("behavior/bugs/3046.zig"); _ = @import("behavior/bugs/3112.zig"); _ = @import("behavior/bugs/3367.zig"); + _ = @import("behavior/bugs/3384.zig"); _ = @import("behavior/bugs/394.zig"); _ = @import("behavior/bugs/421.zig"); _ = @import("behavior/bugs/529.zig"); diff --git a/test/stage1/behavior/bugs/3384.zig b/test/stage1/behavior/bugs/3384.zig new file mode 100644 index 0000000000000000000000000000000000000000..789b0be51648992870483caf148e141d2e3d9018 --- /dev/null +++ b/test/stage1/behavior/bugs/3384.zig @@ -0,0 +1,11 @@ +const std = @import("std"); +const expect = std.testing.expect; + +test "resolve array slice using builtin" { + expect(@hasDecl(@This(), "std") == true); + expect(@hasDecl(@This(), "std"[0..0]) == false); + expect(@hasDecl(@This(), "std"[0..1]) == false); + expect(@hasDecl(@This(), "std"[0..2]) == false); + expect(@hasDecl(@This(), "std"[0..3]) == true); + expect(@hasDecl(@This(), "std"[0..]) == true); +} -- 2.54.0