| 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,7 +13122,6 @@ static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMod |
| 13122 | return true; | 13122 | return true; |
| 13123 | } | 13123 | } |
| 13124 | 13124 | ||
| 13125 | |||
| 13126 | static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { | 13125 | static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 13127 | if (type_is_invalid(value->value.type)) | 13126 | if (type_is_invalid(value->value.type)) |
| 13128 | return nullptr; | 13127 | return nullptr; |
| ... | @@ -13143,11 +13142,11 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { | ... | @@ -13143,11 +13142,11 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 13143 | 13142 | ||
| 13144 | assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); | 13143 | assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 13145 | ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; | 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 | expand_undef_array(ira->codegen, array_val); | 13145 | expand_undef_array(ira->codegen, array_val); |
| 13150 | size_t len = bigint_as_usize(&len_field->data.x_bigint); | 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 | Buf *result = buf_alloc(); | 13150 | Buf *result = buf_alloc(); |
| 13152 | buf_resize(result, len); | 13151 | buf_resize(result, len); |
| 13153 | for (size_t i = 0; i < len; i += 1) { | 13152 | for (size_t i = 0; i < len; i += 1) { |
test/stage1/behavior.zig+1| ... | @@ -35,6 +35,7 @@ comptime { | ... | @@ -35,6 +35,7 @@ comptime { |
| 35 | _ = @import("behavior/bugs/3046.zig"); | 35 | _ = @import("behavior/bugs/3046.zig"); |
| 36 | _ = @import("behavior/bugs/3112.zig"); | 36 | _ = @import("behavior/bugs/3112.zig"); |
| 37 | _ = @import("behavior/bugs/3367.zig"); | 37 | _ = @import("behavior/bugs/3367.zig"); |
| 38 | _ = @import("behavior/bugs/3384.zig"); | ||
| 38 | _ = @import("behavior/bugs/394.zig"); | 39 | _ = @import("behavior/bugs/394.zig"); |
| 39 | _ = @import("behavior/bugs/421.zig"); | 40 | _ = @import("behavior/bugs/421.zig"); |
| 40 | _ = @import("behavior/bugs/529.zig"); | 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 | } | ||