Commit 9c5852aa86

Andrew Kelley <andrew@ziglang.org>
2019-03-03 19:04:04
fix slice of C pointer
closes #2002
1 parent e3b275f
Changed files (3)
src
test
stage1
behavior
src/codegen.cpp
@@ -4570,7 +4570,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
 
         return tmp_struct_ptr;
     } else if (array_type->id == ZigTypeIdPointer) {
-        assert(array_type->data.pointer.ptr_len == PtrLenUnknown);
+        assert(array_type->data.pointer.ptr_len != PtrLenSingle);
         LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
         LLVMValueRef end_val = ir_llvm_value(g, instruction->end);
 
src/ir.cpp
@@ -19757,6 +19757,9 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
                 return ira->codegen->invalid_instruction;
             }
         } else {
+            if (array_type->data.pointer.ptr_len == PtrLenC) {
+                array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown);
+            }
             return_type = get_slice_type(ira->codegen, array_type);
             if (!end) {
                 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value"));
test/stage1/behavior/slice.zig
@@ -1,5 +1,7 @@
-const expect = @import("std").testing.expect;
-const mem = @import("std").mem;
+const std = @import("std");
+const expect = std.testing.expect;
+const expectEqualSlices = std.testing.expectEqualSlices;
+const mem = std.mem;
 
 const x = @intToPtr([*]i32, 0x1000)[0..0x500];
 const y = x[0x100..];
@@ -38,3 +40,10 @@ test "implicitly cast array of size 0 to slice" {
 fn assertLenIsZero(msg: []const u8) void {
     expect(msg.len == 0);
 }
+
+test "C pointer" {
+    var buf: [*c]const u8 = c"kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
+    var len: u32 = 10;
+    var slice = buf[0..len];
+    expectEqualSlices(u8, "kjdhfkjdhf", slice);
+}