Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -28262,15 +28262,25 @@ fn elemPtrArray(
block: *Block,
src: LazySrcLoc,
array_ptr_src: LazySrcLoc,
array_ptr: Air.Inst.Ref,
array_ptr_orig: Air.Inst.Ref,
elem_index_src: LazySrcLoc,
elem_index: Air.Inst.Ref,
init: bool,
oob_safety: bool,
) CompileError!Air.Inst.Ref {
const pt = sema.pt;
const zcu = pt.zcu;
const array_ptr_ty = sema.typeOf(array_ptr);
const array_ptr_ty_orig = sema.typeOf(array_ptr_orig);
var array_ptr_info = array_ptr_ty_orig.ptrInfo(zcu);

// When indexing into a C pointer of an array type, treat it as a single-item pointer to the array: ([*c][_]T)[idx] -> (*[_]T)[idx]
const array_ptr, const array_ptr_ty = if (array_ptr_info.flags.size == .c) blk: {
array_ptr_info.flags.size = .one;
const array_ptr_one_ty = try pt.ptrTypeSema(array_ptr_info);
const array_ptr_one = try block.addBitCast(array_ptr_one_ty, array_ptr_orig);
break :blk .{ array_ptr_one, array_ptr_one_ty };
} else .{ array_ptr_orig, array_ptr_ty_orig };

const array_ty = array_ptr_ty.childType(zcu);
const array_sent = array_ty.sentinel(zcu) != null;
const array_len = array_ty.arrayLen(zcu);
Expand Down
9 changes: 9 additions & 0 deletions test/behavior/pointers.zig
Original file line number Diff line number Diff line change
Expand Up @@ -786,3 +786,12 @@ test "comptime C pointer to optional pointer" {
comptime assert(@TypeOf(inner_ptr) == [*c]const *u8);
comptime assert(@intFromPtr(inner_ptr.*) == 0x1000);
}

test "dereference C pointer of array" {
var arr: [1]u8 = .{0};
const arr_c_ptr = @as([*c][1]u8, &arr);
const arr_ptr = &arr;
arr_c_ptr.*[0] = 1;
try expect(arr[0] == 1);
try expect(&arr_ptr.*[0] == &arr_c_ptr.*[0]);
}