Commit 3464351d1e

Michael Dusan <michael.dusan@gmail.com>
2019-10-10 10:55:09
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
1 parent fd94d78
Changed files (3)
src
test
stage1
behavior
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) {
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);
+}
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");