| author | |
| committer | |
| log | 3464351d1e0a1e840d0b1a6267d0a5bf4113cfcc |
| tree | fbdc987d4377b0126bc8342dfd8cb2d4d465f5b8 |
| parent | fd94d78ffc60f61db0990c18d24a24ef3c56fd4e |
`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 #33843 files changed, 15 insertions(+), 4 deletions(-)
src/ir.cpp+3-4| ... | ... | @@ -13122,7 +13122,6 @@ static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMod |
| 13122 | 13122 | return true; |
| 13123 | 13123 | } |
| 13124 | 13124 | |
| 13125 | ||
| 13126 | 13125 | static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 13127 | 13126 | if (type_is_invalid(value->value.type)) |
| 13128 | 13127 | return nullptr; |
| ... | ... | @@ -13143,11 +13142,11 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 13143 | 13142 | |
| 13144 | 13143 | assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 13145 | 13144 | ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; |
| 13146 | if (array_val->data.x_array.special == ConstArraySpecialBuf) { | |
| 13147 | return array_val->data.x_array.data.s_buf; | |
| 13148 | } | |
| 13149 | 13145 | expand_undef_array(ira->codegen, array_val); |
| 13150 | 13146 | size_t len = bigint_as_usize(&len_field->data.x_bigint); |
| 13147 | if (array_val->data.x_array.special == ConstArraySpecialBuf && len == buf_len(array_val->data.x_array.data.s_buf)) { | |
| 13148 | return array_val->data.x_array.data.s_buf; | |
| 13149 | } | |
| 13151 | 13150 | Buf *result = buf_alloc(); |
| 13152 | 13151 | buf_resize(result, len); |
| 13153 | 13152 | for (size_t i = 0; i < len; i += 1) { |
test/stage1/behavior.zig+1| ... | ... | @@ -35,6 +35,7 @@ comptime { |
| 35 | 35 | _ = @import("behavior/bugs/3046.zig"); |
| 36 | 36 | _ = @import("behavior/bugs/3112.zig"); |
| 37 | 37 | _ = @import("behavior/bugs/3367.zig"); |
| 38 | _ = @import("behavior/bugs/3384.zig"); | |
| 38 | 39 | _ = @import("behavior/bugs/394.zig"); |
| 39 | 40 | _ = @import("behavior/bugs/421.zig"); |
| 40 | 41 | _ = @import("behavior/bugs/529.zig"); |
test/stage1/behavior/bugs/3384.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "resolve array slice using builtin" { | |
| 5 | expect(@hasDecl(@This(), "std") == true); | |
| 6 | expect(@hasDecl(@This(), "std"[0..0]) == false); | |
| 7 | expect(@hasDecl(@This(), "std"[0..1]) == false); | |
| 8 | expect(@hasDecl(@This(), "std"[0..2]) == false); | |
| 9 | expect(@hasDecl(@This(), "std"[0..3]) == true); | |
| 10 | expect(@hasDecl(@This(), "std"[0..]) == true); | |
| 11 | } |