authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-04 01:09:15-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-04 01:39:57-04:00
log96164ce61377b36bcaf0c4087ca9b1ab822b9457
treedb4ab07dd179c8f72a05028edb6ad60bfabd4a74
parent4c273126dfc44cf4fcf9d5d97bf1cb1da07d7bd7

disallow single-item pointer indexing

add pointer arithmetic for unknown length pointer

35 files changed, 584 insertions(+), 443 deletions(-)

doc/langref.html.in+28-20
...@@ -458,7 +458,7 @@ test "string literals" {...@@ -458,7 +458,7 @@ test "string literals" {
458458
459 // A C string literal is a null terminated pointer.459 // A C string literal is a null terminated pointer.
460 const null_terminated_bytes = c"hello";460 const null_terminated_bytes = c"hello";
461 assert(@typeOf(null_terminated_bytes) == *const u8);461 assert(@typeOf(null_terminated_bytes) == [*]const u8);
462 assert(null_terminated_bytes[5] == 0);462 assert(null_terminated_bytes[5] == 0);
463}463}
464 {#code_end#}464 {#code_end#}
...@@ -547,7 +547,7 @@ const c_string_literal =...@@ -547,7 +547,7 @@ const c_string_literal =
547;547;
548 {#code_end#}548 {#code_end#}
549 <p>549 <p>
550 In this example the variable <code>c_string_literal</code> has type <code>*const char</code> and550 In this example the variable <code>c_string_literal</code> has type <code>[*]const char</code> and
551 has a terminating null byte.551 has a terminating null byte.
552 </p>552 </p>
553 {#see_also|@embedFile#}553 {#see_also|@embedFile#}
...@@ -1288,7 +1288,7 @@ const assert = @import("std").debug.assert;...@@ -1288,7 +1288,7 @@ const assert = @import("std").debug.assert;
1288const mem = @import("std").mem;1288const mem = @import("std").mem;
12891289
1290// array literal1290// array literal
1291const message = []u8{'h', 'e', 'l', 'l', 'o'};1291const message = []u8{ 'h', 'e', 'l', 'l', 'o' };
12921292
1293// get the size of an array1293// get the size of an array
1294comptime {1294comptime {
...@@ -1324,11 +1324,11 @@ test "modify an array" {...@@ -1324,11 +1324,11 @@ test "modify an array" {
13241324
1325// array concatenation works if the values are known1325// array concatenation works if the values are known
1326// at compile time1326// at compile time
1327const part_one = []i32{1, 2, 3, 4};1327const part_one = []i32{ 1, 2, 3, 4 };
1328const part_two = []i32{5, 6, 7, 8};1328const part_two = []i32{ 5, 6, 7, 8 };
1329const all_of_it = part_one ++ part_two;1329const all_of_it = part_one ++ part_two;
1330comptime {1330comptime {
1331 assert(mem.eql(i32, all_of_it, []i32{1,2,3,4,5,6,7,8}));1331 assert(mem.eql(i32, all_of_it, []i32{ 1, 2, 3, 4, 5, 6, 7, 8 }));
1332}1332}
13331333
1334// remember that string literals are arrays1334// remember that string literals are arrays
...@@ -1357,7 +1357,7 @@ comptime {...@@ -1357,7 +1357,7 @@ comptime {
1357var fancy_array = init: {1357var fancy_array = init: {
1358 var initial_value: [10]Point = undefined;1358 var initial_value: [10]Point = undefined;
1359 for (initial_value) |*pt, i| {1359 for (initial_value) |*pt, i| {
1360 pt.* = Point {1360 pt.* = Point{
1361 .x = i32(i),1361 .x = i32(i),
1362 .y = i32(i) * 2,1362 .y = i32(i) * 2,
1363 };1363 };
...@@ -1377,7 +1377,7 @@ test "compile-time array initalization" {...@@ -1377,7 +1377,7 @@ test "compile-time array initalization" {
1377// call a function to initialize an array1377// call a function to initialize an array
1378var more_points = []Point{makePoint(3)} ** 10;1378var more_points = []Point{makePoint(3)} ** 10;
1379fn makePoint(x: i32) Point {1379fn makePoint(x: i32) Point {
1380 return Point {1380 return Point{
1381 .x = x,1381 .x = x,
1382 .y = x * 2,1382 .y = x * 2,
1383 };1383 };
...@@ -1414,25 +1414,24 @@ test "address of syntax" {...@@ -1414,25 +1414,24 @@ test "address of syntax" {
1414}1414}
14151415
1416test "pointer array access" {1416test "pointer array access" {
1417 // Pointers do not support pointer arithmetic. If you1417 // Taking an address of an individual element gives a
1418 // need such a thing, use array index syntax:1418 // pointer to a single item. This kind of pointer
1419 // does not support pointer arithmetic.
14191420
1420 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};1421 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1421 const ptr = &array[1];1422 const ptr = &array[2];
1423 assert(@typeOf(ptr) == *u8);
14221424
1423 assert(array[2] == 3);1425 assert(array[2] == 3);
1424 ptr[1] += 1;1426 ptr.* += 1;
1425 assert(array[2] == 4);1427 assert(array[2] == 4);
1426}1428}
14271429
1428test "pointer slicing" {1430test "pointer slicing" {
1429 // In Zig, we prefer using slices over null-terminated pointers.1431 // In Zig, we prefer using slices over null-terminated pointers.
1430 // You can turn a pointer into a slice using slice syntax:1432 // You can turn an array into a slice using slice syntax:
1431 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};1433 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1432 const ptr = &array[1];1434 const slice = array[2..4];
1433 const slice = ptr[1..3];
1434
1435 assert(slice.ptr == &ptr[1]);
1436 assert(slice.len == 2);1435 assert(slice.len == 2);
14371436
1438 // Slices have bounds checking and are therefore protected1437 // Slices have bounds checking and are therefore protected
...@@ -1622,18 +1621,27 @@ fn foo(bytes: []u8) u32 {...@@ -1622,18 +1621,27 @@ fn foo(bytes: []u8) u32 {
1622const assert = @import("std").debug.assert;1621const assert = @import("std").debug.assert;
16231622
1624test "basic slices" {1623test "basic slices" {
1625 var array = []i32{1, 2, 3, 4};1624 var array = []i32{ 1, 2, 3, 4 };
1626 // A slice is a pointer and a length. The difference between an array and1625 // A slice is a pointer and a length. The difference between an array and
1627 // a slice is that the array's length is part of the type and known at1626 // a slice is that the array's length is part of the type and known at
1628 // compile-time, whereas the slice's length is known at runtime.1627 // compile-time, whereas the slice's length is known at runtime.
1629 // Both can be accessed with the `len` field.1628 // Both can be accessed with the `len` field.
1630 const slice = array[0..array.len];1629 const slice = array[0..array.len];
1631 assert(slice.ptr == &array[0]);1630 assert(&slice[0] == &array[0]);
1632 assert(slice.len == array.len);1631 assert(slice.len == array.len);
16331632
1633 // Using the address-of operator on a slice gives a pointer to a single
1634 // item, while using the `ptr` field gives an unknown length pointer.
1635 assert(@typeOf(slice.ptr) == [*]i32);
1636 assert(@typeOf(&slice[0]) == *i32);
1637 assert(@ptrToInt(slice.ptr) == @ptrToInt(&slice[0]));
1638
1634 // Slices have array bounds checking. If you try to access something out1639 // Slices have array bounds checking. If you try to access something out
1635 // of bounds, you'll get a safety check failure:1640 // of bounds, you'll get a safety check failure:
1636 slice[10] += 1;1641 slice[10] += 1;
1642
1643 // Note that `slice.ptr` does not invoke safety checking, while `&slice[0]`
1644 // asserts that the slice has len >= 1.
1637}1645}
1638 {#code_end#}1646 {#code_end#}
1639 <p>This is one reason we prefer slices to pointers.</p>1647 <p>This is one reason we prefer slices to pointers.</p>
...@@ -5937,7 +5945,7 @@ pub const __zig_test_fn_slice = {}; // overwritten later...@@ -5937,7 +5945,7 @@ pub const __zig_test_fn_slice = {}; // overwritten later
5937 {#header_open|C String Literals#}5945 {#header_open|C String Literals#}
5938 {#code_begin|exe#}5946 {#code_begin|exe#}
5939 {#link_libc#}5947 {#link_libc#}
5940extern fn puts(*const u8) void;5948extern fn puts([*]const u8) void;
59415949
5942pub fn main() void {5950pub fn main() void {
5943 puts(c"this has a null terminator");5951 puts(c"this has a null terminator");
src/all_types.hpp+9
...@@ -974,8 +974,14 @@ struct FnTypeId {...@@ -974,8 +974,14 @@ struct FnTypeId {
974uint32_t fn_type_id_hash(FnTypeId*);974uint32_t fn_type_id_hash(FnTypeId*);
975bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);975bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);
976976
977enum PtrLen {
978 PtrLenUnknown,
979 PtrLenSingle,
980};
981
977struct TypeTableEntryPointer {982struct TypeTableEntryPointer {
978 TypeTableEntry *child_type;983 TypeTableEntry *child_type;
984 PtrLen ptr_len;
979 bool is_const;985 bool is_const;
980 bool is_volatile;986 bool is_volatile;
981 uint32_t alignment;987 uint32_t alignment;
...@@ -1397,6 +1403,7 @@ struct TypeId {...@@ -1397,6 +1403,7 @@ struct TypeId {
1397 union {1403 union {
1398 struct {1404 struct {
1399 TypeTableEntry *child_type;1405 TypeTableEntry *child_type;
1406 PtrLen ptr_len;
1400 bool is_const;1407 bool is_const;
1401 bool is_volatile;1408 bool is_volatile;
1402 uint32_t alignment;1409 uint32_t alignment;
...@@ -2268,6 +2275,7 @@ struct IrInstructionElemPtr {...@@ -2268,6 +2275,7 @@ struct IrInstructionElemPtr {
22682275
2269 IrInstruction *array_ptr;2276 IrInstruction *array_ptr;
2270 IrInstruction *elem_index;2277 IrInstruction *elem_index;
2278 PtrLen ptr_len;
2271 bool is_const;2279 bool is_const;
2272 bool safety_check_on;2280 bool safety_check_on;
2273};2281};
...@@ -2419,6 +2427,7 @@ struct IrInstructionPtrType {...@@ -2419,6 +2427,7 @@ struct IrInstructionPtrType {
2419 IrInstruction *child_type;2427 IrInstruction *child_type;
2420 uint32_t bit_offset_start;2428 uint32_t bit_offset_start;
2421 uint32_t bit_offset_end;2429 uint32_t bit_offset_end;
2430 PtrLen ptr_len;
2422 bool is_const;2431 bool is_const;
2423 bool is_volatile;2432 bool is_volatile;
2424};2433};
src/analyze.cpp+36-17
...@@ -381,14 +381,14 @@ TypeTableEntry *get_promise_type(CodeGen *g, TypeTableEntry *result_type) {...@@ -381,14 +381,14 @@ TypeTableEntry *get_promise_type(CodeGen *g, TypeTableEntry *result_type) {
381}381}
382382
383TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,383TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
384 bool is_volatile, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count)384 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count)
385{385{
386 assert(!type_is_invalid(child_type));386 assert(!type_is_invalid(child_type));
387387
388 TypeId type_id = {};388 TypeId type_id = {};
389 TypeTableEntry **parent_pointer = nullptr;389 TypeTableEntry **parent_pointer = nullptr;
390 uint32_t abi_alignment = get_abi_alignment(g, child_type);390 uint32_t abi_alignment = get_abi_alignment(g, child_type);
391 if (unaligned_bit_count != 0 || is_volatile || byte_alignment != abi_alignment) {391 if (unaligned_bit_count != 0 || is_volatile || byte_alignment != abi_alignment || ptr_len != PtrLenSingle) {
392 type_id.id = TypeTableEntryIdPointer;392 type_id.id = TypeTableEntryIdPointer;
393 type_id.data.pointer.child_type = child_type;393 type_id.data.pointer.child_type = child_type;
394 type_id.data.pointer.is_const = is_const;394 type_id.data.pointer.is_const = is_const;
...@@ -396,6 +396,7 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -396,6 +396,7 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
396 type_id.data.pointer.alignment = byte_alignment;396 type_id.data.pointer.alignment = byte_alignment;
397 type_id.data.pointer.bit_offset = bit_offset;397 type_id.data.pointer.bit_offset = bit_offset;
398 type_id.data.pointer.unaligned_bit_count = unaligned_bit_count;398 type_id.data.pointer.unaligned_bit_count = unaligned_bit_count;
399 type_id.data.pointer.ptr_len = ptr_len;
399400
400 auto existing_entry = g->type_table.maybe_get(type_id);401 auto existing_entry = g->type_table.maybe_get(type_id);
401 if (existing_entry)402 if (existing_entry)
...@@ -414,16 +415,17 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -414,16 +415,17 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
414 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);415 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
415 entry->is_copyable = true;416 entry->is_copyable = true;
416417
418 const char *star_str = ptr_len == PtrLenSingle ? "*" : "[*]";
417 const char *const_str = is_const ? "const " : "";419 const char *const_str = is_const ? "const " : "";
418 const char *volatile_str = is_volatile ? "volatile " : "";420 const char *volatile_str = is_volatile ? "volatile " : "";
419 buf_resize(&entry->name, 0);421 buf_resize(&entry->name, 0);
420 if (unaligned_bit_count == 0 && byte_alignment == abi_alignment) {422 if (unaligned_bit_count == 0 && byte_alignment == abi_alignment) {
421 buf_appendf(&entry->name, "*%s%s%s", const_str, volatile_str, buf_ptr(&child_type->name));423 buf_appendf(&entry->name, "%s%s%s%s", star_str, const_str, volatile_str, buf_ptr(&child_type->name));
422 } else if (unaligned_bit_count == 0) {424 } else if (unaligned_bit_count == 0) {
423 buf_appendf(&entry->name, "*align(%" PRIu32 ") %s%s%s", byte_alignment,425 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s", star_str, byte_alignment,
424 const_str, volatile_str, buf_ptr(&child_type->name));426 const_str, volatile_str, buf_ptr(&child_type->name));
425 } else {427 } else {
426 buf_appendf(&entry->name, "*align(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", byte_alignment,428 buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str, byte_alignment,
427 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));429 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));
428 }430 }
429431
...@@ -433,7 +435,9 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -433,7 +435,9 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
433435
434 if (!entry->zero_bits) {436 if (!entry->zero_bits) {
435 assert(byte_alignment > 0);437 assert(byte_alignment > 0);
436 if (is_const || is_volatile || unaligned_bit_count != 0 || byte_alignment != abi_alignment) {438 if (is_const || is_volatile || unaligned_bit_count != 0 || byte_alignment != abi_alignment ||
439 ptr_len != PtrLenSingle)
440 {
437 TypeTableEntry *peer_type = get_pointer_to_type(g, child_type, false);441 TypeTableEntry *peer_type = get_pointer_to_type(g, child_type, false);
438 entry->type_ref = peer_type->type_ref;442 entry->type_ref = peer_type->type_ref;
439 entry->di_type = peer_type->di_type;443 entry->di_type = peer_type->di_type;
...@@ -451,6 +455,7 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -451,6 +455,7 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
451 entry->di_type = g->builtin_types.entry_void->di_type;455 entry->di_type = g->builtin_types.entry_void->di_type;
452 }456 }
453457
458 entry->data.pointer.ptr_len = ptr_len;
454 entry->data.pointer.child_type = child_type;459 entry->data.pointer.child_type = child_type;
455 entry->data.pointer.is_const = is_const;460 entry->data.pointer.is_const = is_const;
456 entry->data.pointer.is_volatile = is_volatile;461 entry->data.pointer.is_volatile = is_volatile;
...@@ -467,7 +472,8 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -467,7 +472,8 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
467}472}
468473
469TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {474TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
470 return get_pointer_to_type_extra(g, child_type, is_const, false, get_abi_alignment(g, child_type), 0, 0);475 return get_pointer_to_type_extra(g, child_type, is_const, false, PtrLenSingle,
476 get_abi_alignment(g, child_type), 0, 0);
471}477}
472478
473TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type) {479TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type) {
...@@ -757,6 +763,7 @@ static void slice_type_common_init(CodeGen *g, TypeTableEntry *pointer_type, Typ...@@ -757,6 +763,7 @@ static void slice_type_common_init(CodeGen *g, TypeTableEntry *pointer_type, Typ
757763
758TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) {764TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) {
759 assert(ptr_type->id == TypeTableEntryIdPointer);765 assert(ptr_type->id == TypeTableEntryIdPointer);
766 assert(ptr_type->data.pointer.ptr_len == PtrLenUnknown);
760767
761 TypeTableEntry **parent_pointer = &ptr_type->data.pointer.slice_parent;768 TypeTableEntry **parent_pointer = &ptr_type->data.pointer.slice_parent;
762 if (*parent_pointer) {769 if (*parent_pointer) {
...@@ -768,14 +775,16 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) {...@@ -768,14 +775,16 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) {
768775
769 // replace the & with [] to go from a ptr type name to a slice type name776 // replace the & with [] to go from a ptr type name to a slice type name
770 buf_resize(&entry->name, 0);777 buf_resize(&entry->name, 0);
771 buf_appendf(&entry->name, "[]%s", buf_ptr(&ptr_type->name) + 1);778 size_t name_offset = (ptr_type->data.pointer.ptr_len == PtrLenSingle) ? 1 : 3;
779 buf_appendf(&entry->name, "[]%s", buf_ptr(&ptr_type->name) + name_offset);
772780
773 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;781 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
774 uint32_t abi_alignment;782 uint32_t abi_alignment = get_abi_alignment(g, child_type);
775 if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||783 if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||
776 ptr_type->data.pointer.alignment != (abi_alignment = get_abi_alignment(g, child_type)))784 ptr_type->data.pointer.alignment != abi_alignment)
777 {785 {
778 TypeTableEntry *peer_ptr_type = get_pointer_to_type(g, child_type, false);786 TypeTableEntry *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false,
787 PtrLenUnknown, abi_alignment, 0, 0);
779 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type);788 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type);
780789
781 slice_type_common_init(g, ptr_type, entry);790 slice_type_common_init(g, ptr_type, entry);
...@@ -799,9 +808,11 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) {...@@ -799,9 +808,11 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) {
799 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||808 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
800 child_ptr_type->data.pointer.alignment != get_abi_alignment(g, grand_child_type))809 child_ptr_type->data.pointer.alignment != get_abi_alignment(g, grand_child_type))
801 {810 {
802 TypeTableEntry *bland_child_ptr_type = get_pointer_to_type(g, grand_child_type, false);811 TypeTableEntry *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false,
812 PtrLenUnknown, get_abi_alignment(g, grand_child_type), 0, 0);
803 TypeTableEntry *bland_child_slice = get_slice_type(g, bland_child_ptr_type);813 TypeTableEntry *bland_child_slice = get_slice_type(g, bland_child_ptr_type);
804 TypeTableEntry *peer_ptr_type = get_pointer_to_type(g, bland_child_slice, false);814 TypeTableEntry *peer_ptr_type = get_pointer_to_type_extra(g, bland_child_slice, false, false,
815 PtrLenUnknown, get_abi_alignment(g, bland_child_slice), 0, 0);
805 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type);816 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type);
806817
807 entry->type_ref = peer_slice_type->type_ref;818 entry->type_ref = peer_slice_type->type_ref;
...@@ -1284,7 +1295,8 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_...@@ -1284,7 +1295,8 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_
1284}1295}
12851296
1286static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **out_buffer) {1297static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **out_buffer) {
1287 TypeTableEntry *ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);1298 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
1299 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
1288 TypeTableEntry *str_type = get_slice_type(g, ptr_type);1300 TypeTableEntry *str_type = get_slice_type(g, ptr_type);
1289 IrInstruction *instr = analyze_const_value(g, scope, node, str_type, nullptr);1301 IrInstruction *instr = analyze_const_value(g, scope, node, str_type, nullptr);
1290 if (type_is_invalid(instr->value.type))1302 if (type_is_invalid(instr->value.type))
...@@ -2954,7 +2966,8 @@ static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) {...@@ -2954,7 +2966,8 @@ static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) {
2954 if (fn_type_id->param_count != 2) {2966 if (fn_type_id->param_count != 2) {
2955 return wrong_panic_prototype(g, proto_node, fn_type);2967 return wrong_panic_prototype(g, proto_node, fn_type);
2956 }2968 }
2957 TypeTableEntry *const_u8_ptr = get_pointer_to_type(g, g->builtin_types.entry_u8, true);2969 TypeTableEntry *const_u8_ptr = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
2970 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
2958 TypeTableEntry *const_u8_slice = get_slice_type(g, const_u8_ptr);2971 TypeTableEntry *const_u8_slice = get_slice_type(g, const_u8_ptr);
2959 if (fn_type_id->param_info[0].type != const_u8_slice) {2972 if (fn_type_id->param_info[0].type != const_u8_slice) {
2960 return wrong_panic_prototype(g, proto_node, fn_type);2973 return wrong_panic_prototype(g, proto_node, fn_type);
...@@ -4994,7 +5007,9 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {...@@ -4994,7 +5007,9 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
49945007
4995 // then make the pointer point to it5008 // then make the pointer point to it
4996 const_val->special = ConstValSpecialStatic;5009 const_val->special = ConstValSpecialStatic;
4997 const_val->type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);5010 // TODO make this `[*]null u8` instead of `[*]u8`
5011 const_val->type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
5012 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
4998 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray;5013 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
4999 const_val->data.x_ptr.data.base_array.array_val = array_val;5014 const_val->data.x_ptr.data.base_array.array_val = array_val;
5000 const_val->data.x_ptr.data.base_array.elem_index = 0;5015 const_val->data.x_ptr.data.base_array.elem_index = 0;
...@@ -5135,7 +5150,9 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr...@@ -5135,7 +5150,9 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr
5135{5150{
5136 assert(array_val->type->id == TypeTableEntryIdArray);5151 assert(array_val->type->id == TypeTableEntryIdArray);
51375152
5138 TypeTableEntry *ptr_type = get_pointer_to_type(g, array_val->type->data.array.child_type, is_const);5153 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, array_val->type->data.array.child_type,
5154 is_const, false, PtrLenUnknown, get_abi_alignment(g, array_val->type->data.array.child_type),
5155 0, 0);
51395156
5140 const_val->special = ConstValSpecialStatic;5157 const_val->special = ConstValSpecialStatic;
5141 const_val->type = get_slice_type(g, ptr_type);5158 const_val->type = get_slice_type(g, ptr_type);
...@@ -5759,6 +5776,7 @@ uint32_t type_id_hash(TypeId x) {...@@ -5759,6 +5776,7 @@ uint32_t type_id_hash(TypeId x) {
5759 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);5776 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
5760 case TypeTableEntryIdPointer:5777 case TypeTableEntryIdPointer:
5761 return hash_ptr(x.data.pointer.child_type) +5778 return hash_ptr(x.data.pointer.child_type) +
5779 ((x.data.pointer.ptr_len == PtrLenSingle) ? (uint32_t)1120226602 : (uint32_t)3200913342) +
5762 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +5780 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +
5763 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +5781 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +
5764 (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +5782 (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +
...@@ -5807,6 +5825,7 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -5807,6 +5825,7 @@ bool type_id_eql(TypeId a, TypeId b) {
58075825
5808 case TypeTableEntryIdPointer:5826 case TypeTableEntryIdPointer:
5809 return a.data.pointer.child_type == b.data.pointer.child_type &&5827 return a.data.pointer.child_type == b.data.pointer.child_type &&
5828 a.data.pointer.ptr_len == b.data.pointer.ptr_len &&
5810 a.data.pointer.is_const == b.data.pointer.is_const &&5829 a.data.pointer.is_const == b.data.pointer.is_const &&
5811 a.data.pointer.is_volatile == b.data.pointer.is_volatile &&5830 a.data.pointer.is_volatile == b.data.pointer.is_volatile &&
5812 a.data.pointer.alignment == b.data.pointer.alignment &&5831 a.data.pointer.alignment == b.data.pointer.alignment &&
src/analyze.hpp+1-1
...@@ -16,7 +16,7 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m...@@ -16,7 +16,7 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m
16TypeTableEntry *new_type_table_entry(TypeTableEntryId id);16TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
17TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);17TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
18TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,18TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
19 bool is_volatile, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count);19 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count);
20uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);20uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
21uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry);21uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry);
22TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits);22TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits);
src/ast_render.cpp+7-1
...@@ -625,7 +625,13 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -625,7 +625,13 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
625 case NodeTypePointerType:625 case NodeTypePointerType:
626 {626 {
627 if (!grouped) fprintf(ar->f, "(");627 if (!grouped) fprintf(ar->f, "(");
628 fprintf(ar->f, "*");628 const char *star = "[*]";
629 if (node->data.pointer_type.star_token != nullptr &&
630 (node->data.pointer_type.star_token->id == TokenIdStar || node->data.pointer_type.star_token->id == TokenIdStarStar))
631 {
632 star = "*";
633 }
634 fprintf(ar->f, "%s", star);
629 if (node->data.pointer_type.align_expr != nullptr) {635 if (node->data.pointer_type.align_expr != nullptr) {
630 fprintf(ar->f, "align(");636 fprintf(ar->f, "align(");
631 render_node_grouped(ar, node->data.pointer_type.align_expr);637 render_node_grouped(ar, node->data.pointer_type.align_expr);
src/codegen.cpp+35-14
...@@ -893,7 +893,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {...@@ -893,7 +893,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
893 assert(val->global_refs->llvm_global);893 assert(val->global_refs->llvm_global);
894 }894 }
895895
896 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);896 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
897 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
897 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);898 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
898 return LLVMConstBitCast(val->global_refs->llvm_global, LLVMPointerType(str_type->type_ref, 0));899 return LLVMConstBitCast(val->global_refs->llvm_global, LLVMPointerType(str_type->type_ref, 0));
899}900}
...@@ -1461,7 +1462,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1461,7 +1462,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1461 LLVMValueRef full_buf_ptr = LLVMConstInBoundsGEP(global_array, full_buf_ptr_indices, 2);1462 LLVMValueRef full_buf_ptr = LLVMConstInBoundsGEP(global_array, full_buf_ptr_indices, 2);
14621463
14631464
1464 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);1465 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
1466 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
1465 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);1467 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
1466 LLVMValueRef global_slice_fields[] = {1468 LLVMValueRef global_slice_fields[] = {
1467 full_buf_ptr,1469 full_buf_ptr,
...@@ -2212,9 +2214,13 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -2212,9 +2214,13 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
2212 IrInstruction *op2 = bin_op_instruction->op2;2214 IrInstruction *op2 = bin_op_instruction->op2;
22132215
2214 assert(op1->value.type == op2->value.type || op_id == IrBinOpBitShiftLeftLossy ||2216 assert(op1->value.type == op2->value.type || op_id == IrBinOpBitShiftLeftLossy ||
2215 op_id == IrBinOpBitShiftLeftExact || op_id == IrBinOpBitShiftRightLossy ||2217 op_id == IrBinOpBitShiftLeftExact || op_id == IrBinOpBitShiftRightLossy ||
2216 op_id == IrBinOpBitShiftRightExact ||2218 op_id == IrBinOpBitShiftRightExact ||
2217 (op1->value.type->id == TypeTableEntryIdErrorSet && op2->value.type->id == TypeTableEntryIdErrorSet));2219 (op1->value.type->id == TypeTableEntryIdErrorSet && op2->value.type->id == TypeTableEntryIdErrorSet) ||
2220 (op1->value.type->id == TypeTableEntryIdPointer &&
2221 (op_id == IrBinOpAdd || op_id == IrBinOpSub) &&
2222 op1->value.type->data.pointer.ptr_len == PtrLenUnknown)
2223 );
2218 TypeTableEntry *type_entry = op1->value.type;2224 TypeTableEntry *type_entry = op1->value.type;
22192225
2220 bool want_runtime_safety = bin_op_instruction->safety_check_on &&2226 bool want_runtime_safety = bin_op_instruction->safety_check_on &&
...@@ -2222,6 +2228,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -2222,6 +2228,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
22222228
2223 LLVMValueRef op1_value = ir_llvm_value(g, op1);2229 LLVMValueRef op1_value = ir_llvm_value(g, op1);
2224 LLVMValueRef op2_value = ir_llvm_value(g, op2);2230 LLVMValueRef op2_value = ir_llvm_value(g, op2);
2231
2232
2225 switch (op_id) {2233 switch (op_id) {
2226 case IrBinOpInvalid:2234 case IrBinOpInvalid:
2227 case IrBinOpArrayCat:2235 case IrBinOpArrayCat:
...@@ -2260,7 +2268,11 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -2260,7 +2268,11 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
2260 }2268 }
2261 case IrBinOpAdd:2269 case IrBinOpAdd:
2262 case IrBinOpAddWrap:2270 case IrBinOpAddWrap:
2263 if (type_entry->id == TypeTableEntryIdFloat) {2271 if (type_entry->id == TypeTableEntryIdPointer) {
2272 assert(type_entry->data.pointer.ptr_len == PtrLenUnknown);
2273 // TODO runtime safety
2274 return LLVMBuildInBoundsGEP(g->builder, op1_value, &op2_value, 1, "");
2275 } else if (type_entry->id == TypeTableEntryIdFloat) {
2264 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));2276 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
2265 return LLVMBuildFAdd(g->builder, op1_value, op2_value, "");2277 return LLVMBuildFAdd(g->builder, op1_value, op2_value, "");
2266 } else if (type_entry->id == TypeTableEntryIdInt) {2278 } else if (type_entry->id == TypeTableEntryIdInt) {
...@@ -2323,7 +2335,12 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -2323,7 +2335,12 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
2323 }2335 }
2324 case IrBinOpSub:2336 case IrBinOpSub:
2325 case IrBinOpSubWrap:2337 case IrBinOpSubWrap:
2326 if (type_entry->id == TypeTableEntryIdFloat) {2338 if (type_entry->id == TypeTableEntryIdPointer) {
2339 assert(type_entry->data.pointer.ptr_len == PtrLenUnknown);
2340 // TODO runtime safety
2341 LLVMValueRef subscript_value = LLVMBuildNeg(g->builder, op2_value, "");
2342 return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, "");
2343 } else if (type_entry->id == TypeTableEntryIdFloat) {
2327 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));2344 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
2328 return LLVMBuildFSub(g->builder, op1_value, op2_value, "");2345 return LLVMBuildFSub(g->builder, op1_value, op2_value, "");
2329 } else if (type_entry->id == TypeTableEntryIdInt) {2346 } else if (type_entry->id == TypeTableEntryIdInt) {
...@@ -2770,7 +2787,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,...@@ -2770,7 +2787,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
2770 if (have_init_expr) {2787 if (have_init_expr) {
2771 assert(var->value->type == init_value->value.type);2788 assert(var->value->type == init_value->value.type);
2772 TypeTableEntry *var_ptr_type = get_pointer_to_type_extra(g, var->value->type, false, false,2789 TypeTableEntry *var_ptr_type = get_pointer_to_type_extra(g, var->value->type, false, false,
2773 var->align_bytes, 0, 0);2790 PtrLenSingle, var->align_bytes, 0, 0);
2774 gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));2791 gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));
2775 } else {2792 } else {
2776 bool want_safe = ir_want_runtime_safety(g, &decl_var_instruction->base);2793 bool want_safe = ir_want_runtime_safety(g, &decl_var_instruction->base);
...@@ -4172,7 +4189,7 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable,...@@ -4172,7 +4189,7 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable,
4172 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);4189 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);
41734190
4174 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,4191 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,
4175 false, false, field_align_bytes,4192 false, false, PtrLenSingle, field_align_bytes,
4176 (uint32_t)type_struct_field->packed_bits_offset, (uint32_t)type_struct_field->unaligned_bit_count);4193 (uint32_t)type_struct_field->packed_bits_offset, (uint32_t)type_struct_field->unaligned_bit_count);
41774194
4178 gen_assign_raw(g, field_ptr, ptr_type, value);4195 gen_assign_raw(g, field_ptr, ptr_type, value);
...@@ -4188,7 +4205,7 @@ static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, I...@@ -4188,7 +4205,7 @@ static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, I
41884205
4189 uint32_t field_align_bytes = get_abi_alignment(g, type_union_field->type_entry);4206 uint32_t field_align_bytes = get_abi_alignment(g, type_union_field->type_entry);
4190 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, type_union_field->type_entry,4207 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, type_union_field->type_entry,
4191 false, false, field_align_bytes,4208 false, false, PtrLenSingle, field_align_bytes,
4192 0, 0);4209 0, 0);
41934210
4194 LLVMValueRef uncasted_union_ptr;4211 LLVMValueRef uncasted_union_ptr;
...@@ -4435,7 +4452,8 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f...@@ -4435,7 +4452,8 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
44354452
4436 LLVMPositionBuilderAtEnd(g->builder, ok_block);4453 LLVMPositionBuilderAtEnd(g->builder, ok_block);
4437 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_payload_index, "");4454 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_payload_index, "");
4438 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);4455 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false,
4456 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
4439 TypeTableEntry *slice_type = get_slice_type(g, u8_ptr_type);4457 TypeTableEntry *slice_type = get_slice_type(g, u8_ptr_type);
4440 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;4458 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
4441 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, payload_ptr, ptr_field_index, "");4459 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, payload_ptr, ptr_field_index, "");
...@@ -5377,7 +5395,8 @@ static void generate_error_name_table(CodeGen *g) {...@@ -5377,7 +5395,8 @@ static void generate_error_name_table(CodeGen *g) {
53775395
5378 assert(g->errors_by_index.length > 0);5396 assert(g->errors_by_index.length > 0);
53795397
5380 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);5398 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
5399 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
5381 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);5400 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
53825401
5383 LLVMValueRef *values = allocate<LLVMValueRef>(g->errors_by_index.length);5402 LLVMValueRef *values = allocate<LLVMValueRef>(g->errors_by_index.length);
...@@ -5415,7 +5434,8 @@ static void generate_error_name_table(CodeGen *g) {...@@ -5415,7 +5434,8 @@ static void generate_error_name_table(CodeGen *g) {
5415}5434}
54165435
5417static void generate_enum_name_tables(CodeGen *g) {5436static void generate_enum_name_tables(CodeGen *g) {
5418 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);5437 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
5438 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
5419 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);5439 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
54205440
5421 TypeTableEntry *usize = g->builtin_types.entry_usize;5441 TypeTableEntry *usize = g->builtin_types.entry_usize;
...@@ -6869,7 +6889,8 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {...@@ -6869,7 +6889,8 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
6869 exit(0);6889 exit(0);
6870 }6890 }
68716891
6872 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);6892 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
6893 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0);
6873 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);6894 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
6874 TypeTableEntry *fn_type = get_test_fn_type(g);6895 TypeTableEntry *fn_type = get_test_fn_type(g);
68756896
src/ir.cpp+126-51
...@@ -1009,12 +1009,13 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so...@@ -1009,12 +1009,13 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so
1009}1009}
10101010
1011static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr,1011static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr,
1012 IrInstruction *elem_index, bool safety_check_on)1012 IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len)
1013{1013{
1014 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);1014 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);
1015 instruction->array_ptr = array_ptr;1015 instruction->array_ptr = array_ptr;
1016 instruction->elem_index = elem_index;1016 instruction->elem_index = elem_index;
1017 instruction->safety_check_on = safety_check_on;1017 instruction->safety_check_on = safety_check_on;
1018 instruction->ptr_len = ptr_len;
10181019
1019 ir_ref_instruction(array_ptr, irb->current_basic_block);1020 ir_ref_instruction(array_ptr, irb->current_basic_block);
1020 ir_ref_instruction(elem_index, irb->current_basic_block);1021 ir_ref_instruction(elem_index, irb->current_basic_block);
...@@ -1022,15 +1023,6 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s...@@ -1022,15 +1023,6 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s
1022 return &instruction->base;1023 return &instruction->base;
1023}1024}
10241025
1025static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
1026 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on)
1027{
1028 IrInstruction *new_instruction = ir_build_elem_ptr(irb, old_instruction->scope,
1029 old_instruction->source_node, array_ptr, elem_index, safety_check_on);
1030 ir_link_new_instruction(new_instruction, old_instruction);
1031 return new_instruction;
1032}
1033
1034static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node,1026static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node,
1035 IrInstruction *container_ptr, IrInstruction *field_name_expr)1027 IrInstruction *container_ptr, IrInstruction *field_name_expr)
1036{1028{
...@@ -1188,14 +1180,15 @@ static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instru...@@ -1188,14 +1180,15 @@ static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instru
1188}1180}
11891181
1190static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node,1182static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
1191 IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value,1183 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len,
1192 uint32_t bit_offset_start, uint32_t bit_offset_end)1184 IrInstruction *align_value, uint32_t bit_offset_start, uint32_t bit_offset_end)
1193{1185{
1194 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node);1186 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node);
1195 ptr_type_of_instruction->align_value = align_value;1187 ptr_type_of_instruction->align_value = align_value;
1196 ptr_type_of_instruction->child_type = child_type;1188 ptr_type_of_instruction->child_type = child_type;
1197 ptr_type_of_instruction->is_const = is_const;1189 ptr_type_of_instruction->is_const = is_const;
1198 ptr_type_of_instruction->is_volatile = is_volatile;1190 ptr_type_of_instruction->is_volatile = is_volatile;
1191 ptr_type_of_instruction->ptr_len = ptr_len;
1199 ptr_type_of_instruction->bit_offset_start = bit_offset_start;1192 ptr_type_of_instruction->bit_offset_start = bit_offset_start;
1200 ptr_type_of_instruction->bit_offset_end = bit_offset_end;1193 ptr_type_of_instruction->bit_offset_end = bit_offset_end;
12011194
...@@ -3547,7 +3540,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode...@@ -3547,7 +3540,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
3547 return subscript_instruction;3540 return subscript_instruction;
35483541
3549 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,3542 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
3550 subscript_instruction, true);3543 subscript_instruction, true, PtrLenSingle);
3551 if (lval.is_ptr)3544 if (lval.is_ptr)
3552 return ptr_instruction;3545 return ptr_instruction;
35533546
...@@ -4626,6 +4619,11 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *...@@ -4626,6 +4619,11 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *
46264619
4627static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {4620static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {
4628 assert(node->type == NodeTypePointerType);4621 assert(node->type == NodeTypePointerType);
4622 // The null check here is for C imports which don't set a token on the AST node. We could potentially
4623 // update that code to create a fake token and then remove this check.
4624 PtrLen ptr_len = (node->data.pointer_type.star_token != nullptr &&
4625 (node->data.pointer_type.star_token->id == TokenIdStar ||
4626 node->data.pointer_type.star_token->id == TokenIdStarStar)) ? PtrLenSingle : PtrLenUnknown;
4629 bool is_const = node->data.pointer_type.is_const;4627 bool is_const = node->data.pointer_type.is_const;
4630 bool is_volatile = node->data.pointer_type.is_volatile;4628 bool is_volatile = node->data.pointer_type.is_volatile;
4631 AstNode *expr_node = node->data.pointer_type.op_expr;4629 AstNode *expr_node = node->data.pointer_type.op_expr;
...@@ -4675,7 +4673,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode...@@ -4675,7 +4673,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
4675 }4673 }
46764674
4677 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile,4675 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile,
4678 align_value, bit_offset_start, bit_offset_end);4676 ptr_len, align_value, bit_offset_start, bit_offset_end);
4679}4677}
46804678
4681static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,4679static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,
...@@ -5172,7 +5170,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5172,7 +5170,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
5172 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime));5170 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime));
51735171
5174 ir_set_cursor_at_end_and_append_block(irb, body_block);5172 ir_set_cursor_at_end_and_append_block(irb, body_block);
5175 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false);5173 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle);
5176 IrInstruction *elem_val;5174 IrInstruction *elem_val;
5177 if (node->data.for_expr.elem_is_ptr) {5175 if (node->data.for_expr.elem_is_ptr) {
5178 elem_val = elem_ptr;5176 elem_val = elem_ptr;
...@@ -6811,9 +6809,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6811,9 +6809,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
68116809
6812 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final);6810 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final);
6813 if (type_has_bits(return_type)) {6811 if (type_has_bits(return_type)) {
6812 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
6813 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
6814 false, false, PtrLenUnknown, get_abi_alignment(irb->codegen, irb->codegen->builtin_types.entry_u8),
6815 0, 0));
6814 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);6816 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
6815 IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, result_ptr);6817 IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, result_ptr);
6816 IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type,6818 IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len,
6817 irb->exec->coro_result_field_ptr);6819 irb->exec->coro_result_field_ptr);
6818 IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node,6820 IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node,
6819 fn_entry->type_entry->data.fn.fn_type_id.return_type);6821 fn_entry->type_entry->data.fn.fn_type_id.return_type);
...@@ -7691,6 +7693,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7691,6 +7693,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7691 // pointer const7693 // pointer const
7692 if (expected_type->id == TypeTableEntryIdPointer &&7694 if (expected_type->id == TypeTableEntryIdPointer &&
7693 actual_type->id == TypeTableEntryIdPointer &&7695 actual_type->id == TypeTableEntryIdPointer &&
7696 (actual_type->data.pointer.ptr_len == expected_type->data.pointer.ptr_len) &&
7694 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) &&7697 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) &&
7695 (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile) &&7698 (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile) &&
7696 actual_type->data.pointer.bit_offset == expected_type->data.pointer.bit_offset &&7699 actual_type->data.pointer.bit_offset == expected_type->data.pointer.bit_offset &&
...@@ -8644,7 +8647,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8644,7 +8647,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
86448647
8645 if (convert_to_const_slice) {8648 if (convert_to_const_slice) {
8646 assert(prev_inst->value.type->id == TypeTableEntryIdArray);8649 assert(prev_inst->value.type->id == TypeTableEntryIdArray);
8647 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);8650 TypeTableEntry *ptr_type = get_pointer_to_type_extra(
8651 ira->codegen, prev_inst->value.type->data.array.child_type,
8652 true, false, PtrLenUnknown,
8653 get_abi_alignment(ira->codegen, prev_inst->value.type->data.array.child_type),
8654 0, 0);
8648 TypeTableEntry *slice_type = get_slice_type(ira->codegen, ptr_type);8655 TypeTableEntry *slice_type = get_slice_type(ira->codegen, ptr_type);
8649 if (err_set_type != nullptr) {8656 if (err_set_type != nullptr) {
8650 return get_error_union_type(ira->codegen, err_set_type, slice_type);8657 return get_error_union_type(ira->codegen, err_set_type, slice_type);
...@@ -8961,7 +8968,7 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio...@@ -8961,7 +8968,7 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio
8961 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align)8968 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align)
8962{8969{
8963 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type,8970 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type,
8964 ptr_is_const, ptr_is_volatile, ptr_align, 0, 0);8971 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0);
8965 IrInstruction *const_instr = ir_get_const(ira, instruction);8972 IrInstruction *const_instr = ir_get_const(ira, instruction);
8966 ConstExprValue *const_val = &const_instr->value;8973 ConstExprValue *const_val = &const_instr->value;
8967 const_val->type = ptr_type;8974 const_val->type = ptr_type;
...@@ -9302,7 +9309,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi...@@ -9302,7 +9309,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
9302 }9309 }
93039310
9304 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,9311 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,
9305 is_const, is_volatile, get_abi_alignment(ira->codegen, value->value.type), 0, 0);9312 is_const, is_volatile, PtrLenSingle, get_abi_alignment(ira->codegen, value->value.type), 0, 0);
9306 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,9313 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
9307 source_instruction->source_node, value, is_const, is_volatile);9314 source_instruction->source_node, value, is_const, is_volatile);
9308 new_instruction->value.type = ptr_type;9315 new_instruction->value.type = ptr_type;
...@@ -10399,7 +10406,9 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {...@@ -10399,7 +10406,9 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
10399 if (type_is_invalid(value->value.type))10406 if (type_is_invalid(value->value.type))
10400 return nullptr;10407 return nullptr;
1040110408
10402 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);10409 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
10410 true, false, PtrLenUnknown,
10411 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
10403 TypeTableEntry *str_type = get_slice_type(ira->codegen, ptr_type);10412 TypeTableEntry *str_type = get_slice_type(ira->codegen, ptr_type);
10404 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type);10413 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type);
10405 if (type_is_invalid(casted_value->value.type))10414 if (type_is_invalid(casted_value->value.type))
...@@ -11054,11 +11063,27 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *...@@ -11054,11 +11063,27 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
11054static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {11063static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
11055 IrInstruction *op1 = bin_op_instruction->op1->other;11064 IrInstruction *op1 = bin_op_instruction->op1->other;
11056 IrInstruction *op2 = bin_op_instruction->op2->other;11065 IrInstruction *op2 = bin_op_instruction->op2->other;
11066 IrBinOp op_id = bin_op_instruction->op_id;
11067
11068 // look for pointer math
11069 if (op1->value.type->id == TypeTableEntryIdPointer && op1->value.type->data.pointer.ptr_len == PtrLenUnknown &&
11070 (op_id == IrBinOpAdd || op_id == IrBinOpSub))
11071 {
11072 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize);
11073 if (casted_op2 == ira->codegen->invalid_instruction)
11074 return ira->codegen->builtin_types.entry_invalid;
11075
11076 IrInstruction *result = ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.scope,
11077 bin_op_instruction->base.source_node, op_id, op1, casted_op2, true);
11078 result->value.type = op1->value.type;
11079 ir_link_new_instruction(result, &bin_op_instruction->base);
11080 return result->value.type;
11081 }
11082
11057 IrInstruction *instructions[] = {op1, op2};11083 IrInstruction *instructions[] = {op1, op2};
11058 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, nullptr, instructions, 2);11084 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, nullptr, instructions, 2);
11059 if (type_is_invalid(resolved_type))11085 if (type_is_invalid(resolved_type))
11060 return resolved_type;11086 return resolved_type;
11061 IrBinOp op_id = bin_op_instruction->op_id;
1106211087
11063 bool is_int = resolved_type->id == TypeTableEntryIdInt || resolved_type->id == TypeTableEntryIdNumLitInt;11088 bool is_int = resolved_type->id == TypeTableEntryIdInt || resolved_type->id == TypeTableEntryIdNumLitInt;
11064 bool is_float = resolved_type->id == TypeTableEntryIdFloat || resolved_type->id == TypeTableEntryIdNumLitFloat;11089 bool is_float = resolved_type->id == TypeTableEntryIdFloat || resolved_type->id == TypeTableEntryIdNumLitFloat;
...@@ -11331,7 +11356,8 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *...@@ -11331,7 +11356,8 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *
1133111356
11332 out_array_val = out_val;11357 out_array_val = out_val;
11333 } else if (is_slice(op1_type) || is_slice(op2_type)) {11358 } else if (is_slice(op1_type) || is_slice(op2_type)) {
11334 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, child_type, true);11359 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
11360 true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, child_type), 0, 0);
11335 result_type = get_slice_type(ira->codegen, ptr_type);11361 result_type = get_slice_type(ira->codegen, ptr_type);
11336 out_array_val = create_const_vals(1);11362 out_array_val = create_const_vals(1);
11337 out_array_val->special = ConstValSpecialStatic;11363 out_array_val->special = ConstValSpecialStatic;
...@@ -11351,7 +11377,9 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *...@@ -11351,7 +11377,9 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *
11351 } else {11377 } else {
11352 new_len += 1; // null byte11378 new_len += 1; // null byte
1135311379
11354 result_type = get_pointer_to_type(ira->codegen, child_type, true);11380 // TODO make this `[*]null T` instead of `[*]T`
11381 result_type = get_pointer_to_type_extra(ira->codegen, child_type, true, false,
11382 PtrLenUnknown, get_abi_alignment(ira->codegen, child_type), 0, 0);
1135511383
11356 out_array_val = create_const_vals(1);11384 out_array_val = create_const_vals(1);
11357 out_array_val->special = ConstValSpecialStatic;11385 out_array_val->special = ConstValSpecialStatic;
...@@ -12173,7 +12201,7 @@ no_mem_slot:...@@ -12173,7 +12201,7 @@ no_mem_slot:
12173 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb,12201 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb,
12174 instruction->scope, instruction->source_node, var);12202 instruction->scope, instruction->source_node, var);
12175 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->value->type,12203 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->value->type,
12176 var->src_is_const, is_volatile, var->align_bytes, 0, 0);12204 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0);
12177 type_ensure_zero_bits_known(ira->codegen, var->value->type);12205 type_ensure_zero_bits_known(ira->codegen, var->value->type);
1217812206
12179 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);12207 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);
...@@ -12352,7 +12380,9 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12352,7 +12380,9 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1235212380
12353 IrInstruction *casted_new_stack = nullptr;12381 IrInstruction *casted_new_stack = nullptr;
12354 if (call_instruction->new_stack != nullptr) {12382 if (call_instruction->new_stack != nullptr) {
12355 TypeTableEntry *u8_ptr = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false);12383 TypeTableEntry *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
12384 false, false, PtrLenUnknown,
12385 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
12356 TypeTableEntry *u8_slice = get_slice_type(ira->codegen, u8_ptr);12386 TypeTableEntry *u8_slice = get_slice_type(ira->codegen, u8_ptr);
12357 IrInstruction *new_stack = call_instruction->new_stack->other;12387 IrInstruction *new_stack = call_instruction->new_stack->other;
12358 if (type_is_invalid(new_stack->value.type))12388 if (type_is_invalid(new_stack->value.type))
...@@ -13112,10 +13142,21 @@ static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, ui...@@ -13112,10 +13142,21 @@ static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, ui
13112 return get_pointer_to_type_extra(g,13142 return get_pointer_to_type_extra(g,
13113 ptr_type->data.pointer.child_type,13143 ptr_type->data.pointer.child_type,
13114 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,13144 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
13145 ptr_type->data.pointer.ptr_len,
13115 new_align,13146 new_align,
13116 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count);13147 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count);
13117}13148}
1311813149
13150static TypeTableEntry *adjust_ptr_len(CodeGen *g, TypeTableEntry *ptr_type, PtrLen ptr_len) {
13151 assert(ptr_type->id == TypeTableEntryIdPointer);
13152 return get_pointer_to_type_extra(g,
13153 ptr_type->data.pointer.child_type,
13154 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
13155 ptr_len,
13156 ptr_type->data.pointer.alignment,
13157 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count);
13158}
13159
13119static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {13160static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {
13120 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other;13161 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other;
13121 if (type_is_invalid(array_ptr->value.type))13162 if (type_is_invalid(array_ptr->value.type))
...@@ -13146,6 +13187,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13146,6 +13187,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
13146 if (ptr_type->data.pointer.unaligned_bit_count == 0) {13187 if (ptr_type->data.pointer.unaligned_bit_count == 0) {
13147 return_type = get_pointer_to_type_extra(ira->codegen, child_type,13188 return_type = get_pointer_to_type_extra(ira->codegen, child_type,
13148 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,13189 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
13190 elem_ptr_instruction->ptr_len,
13149 ptr_type->data.pointer.alignment, 0, 0);13191 ptr_type->data.pointer.alignment, 0, 0);
13150 } else {13192 } else {
13151 uint64_t elem_val_scalar;13193 uint64_t elem_val_scalar;
...@@ -13157,12 +13199,19 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13157,12 +13199,19 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1315713199
13158 return_type = get_pointer_to_type_extra(ira->codegen, child_type,13200 return_type = get_pointer_to_type_extra(ira->codegen, child_type,
13159 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,13201 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
13202 elem_ptr_instruction->ptr_len,
13160 1, (uint32_t)bit_offset, (uint32_t)bit_width);13203 1, (uint32_t)bit_offset, (uint32_t)bit_width);
13161 }13204 }
13162 } else if (array_type->id == TypeTableEntryIdPointer) {13205 } else if (array_type->id == TypeTableEntryIdPointer) {
13163 return_type = array_type;13206 if (array_type->data.pointer.ptr_len == PtrLenSingle) {
13207 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
13208 buf_sprintf("indexing not allowed on pointer to single item"));
13209 return ira->codegen->builtin_types.entry_invalid;
13210 }
13211 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len);
13164 } else if (is_slice(array_type)) {13212 } else if (is_slice(array_type)) {
13165 return_type = array_type->data.structure.fields[slice_ptr_index].type_entry;13213 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry,
13214 elem_ptr_instruction->ptr_len);
13166 } else if (array_type->id == TypeTableEntryIdArgTuple) {13215 } else if (array_type->id == TypeTableEntryIdArgTuple) {
13167 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);13216 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
13168 if (!ptr_val)13217 if (!ptr_val)
...@@ -13304,8 +13353,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13304,8 +13353,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
13304 } else if (is_slice(array_type)) {13353 } else if (is_slice(array_type)) {
13305 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];13354 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
13306 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {13355 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
13307 ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr,13356 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,
13308 casted_elem_index, false);13357 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len);
13358 result->value.type = return_type;
13359 ir_link_new_instruction(result, &elem_ptr_instruction->base);
13309 return return_type;13360 return return_type;
13310 }13361 }
13311 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];13362 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];
...@@ -13373,8 +13424,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13373,8 +13424,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
13373 }13424 }
13374 }13425 }
1337513426
13376 ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr,13427 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,
13377 casted_elem_index, safety_check_on);13428 array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len);
13429 result->value.type = return_type;
13430 ir_link_new_instruction(result, &elem_ptr_instruction->base);
13378 return return_type;13431 return return_type;
13379}13432}
1338013433
...@@ -13449,7 +13502,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -13449,7 +13502,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
13449 return ira->codegen->invalid_instruction;13502 return ira->codegen->invalid_instruction;
13450 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];13503 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
13451 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,13504 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
13452 is_const, is_volatile, align_bytes,13505 is_const, is_volatile, PtrLenSingle, align_bytes,
13453 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),13506 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),
13454 (uint32_t)unaligned_bit_count_for_result_type);13507 (uint32_t)unaligned_bit_count_for_result_type);
13455 IrInstruction *result = ir_get_const(ira, source_instr);13508 IrInstruction *result = ir_get_const(ira, source_instr);
...@@ -13465,6 +13518,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -13465,6 +13518,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
13465 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,13518 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,
13466 container_ptr, field);13519 container_ptr, field);
13467 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,13520 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
13521 PtrLenSingle,
13468 align_bytes,13522 align_bytes,
13469 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),13523 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),
13470 (uint32_t)unaligned_bit_count_for_result_type);13524 (uint32_t)unaligned_bit_count_for_result_type);
...@@ -13511,7 +13565,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -13511,7 +13565,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
13511 payload_val->type = field_type;13565 payload_val->type = field_type;
13512 }13566 }
1351313567
13514 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, is_const, is_volatile,13568 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
13569 is_const, is_volatile,
13570 PtrLenSingle,
13515 get_abi_alignment(ira->codegen, field_type), 0, 0);13571 get_abi_alignment(ira->codegen, field_type), 0, 0);
1351613572
13517 IrInstruction *result = ir_get_const(ira, source_instr);13573 IrInstruction *result = ir_get_const(ira, source_instr);
...@@ -13526,7 +13582,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -13526,7 +13582,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1352613582
13527 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field);13583 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field);
13528 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,13584 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
13529 get_abi_alignment(ira->codegen, field->type_entry), 0, 0);13585 PtrLenSingle, get_abi_alignment(ira->codegen, field->type_entry), 0, 0);
13530 return result;13586 return result;
13531 } else {13587 } else {
13532 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,13588 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
...@@ -14119,7 +14175,7 @@ static TypeTableEntry *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,...@@ -14119,7 +14175,7 @@ static TypeTableEntry *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
14119 if (type_entry->id == TypeTableEntryIdArray) {14175 if (type_entry->id == TypeTableEntryIdArray) {
14120 ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, false);14176 ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, false);
14121 } else if (is_slice(type_entry)) {14177 } else if (is_slice(type_entry)) {
14122 ptr_type = type_entry->data.structure.fields[0].type_entry;14178 ptr_type = adjust_ptr_len(ira->codegen, type_entry->data.structure.fields[0].type_entry, PtrLenSingle);
14123 } else if (type_entry->id == TypeTableEntryIdArgTuple) {14179 } else if (type_entry->id == TypeTableEntryIdArgTuple) {
14124 ConstExprValue *arg_tuple_val = ir_resolve_const(ira, value, UndefBad);14180 ConstExprValue *arg_tuple_val = ir_resolve_const(ira, value, UndefBad);
14125 if (!arg_tuple_val)14181 if (!arg_tuple_val)
...@@ -14367,7 +14423,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -14367,7 +14423,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
14367 {14423 {
14368 type_ensure_zero_bits_known(ira->codegen, child_type);14424 type_ensure_zero_bits_known(ira->codegen, child_type);
14369 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,14425 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
14370 is_const, is_volatile, align_bytes, 0, 0);14426 is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0);
14371 TypeTableEntry *result_type = get_slice_type(ira->codegen, slice_ptr_type);14427 TypeTableEntry *result_type = get_slice_type(ira->codegen, slice_ptr_type);
14372 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base);14428 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base);
14373 out_val->data.x_type = result_type;14429 out_val->data.x_type = result_type;
...@@ -14619,6 +14675,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,...@@ -14619,6 +14675,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,
14619 TypeTableEntry *child_type = type_entry->data.maybe.child_type;14675 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
14620 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type,14676 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
14621 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,14677 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
14678 PtrLenSingle,
14622 get_abi_alignment(ira->codegen, child_type), 0, 0);14679 get_abi_alignment(ira->codegen, child_type), 0, 0);
1462314680
14624 if (instr_is_comptime(value)) {14681 if (instr_is_comptime(value)) {
...@@ -15566,7 +15623,8 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc...@@ -15566,7 +15623,8 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
15566 if (type_is_invalid(casted_value->value.type))15623 if (type_is_invalid(casted_value->value.type))
15567 return ira->codegen->builtin_types.entry_invalid;15624 return ira->codegen->builtin_types.entry_invalid;
1556815625
15569 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);15626 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
15627 true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
15570 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);15628 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
15571 if (casted_value->value.special == ConstValSpecialStatic) {15629 if (casted_value->value.special == ConstValSpecialStatic) {
15572 ErrorTableEntry *err = casted_value->value.data.x_err_set;15630 ErrorTableEntry *err = casted_value->value.data.x_err_set;
...@@ -15607,7 +15665,11 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIn...@@ -15607,7 +15665,11 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIn
15607 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope,15665 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope,
15608 instruction->base.source_node, target);15666 instruction->base.source_node, target);
15609 ir_link_new_instruction(result, &instruction->base);15667 ir_link_new_instruction(result, &instruction->base);
15610 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);15668 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(
15669 ira->codegen, ira->codegen->builtin_types.entry_u8,
15670 true, false, PtrLenUnknown,
15671 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8),
15672 0, 0);
15611 result->value.type = get_slice_type(ira->codegen, u8_ptr_type);15673 result->value.type = get_slice_type(ira->codegen, u8_ptr_type);
15612 return result->value.type;15674 return result->value.type;
15613}15675}
...@@ -15660,6 +15722,7 @@ static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,...@@ -15660,6 +15722,7 @@ static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
15660 TypeTableEntry *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,15722 TypeTableEntry *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
15661 field_ptr->value.type->data.pointer.is_const,15723 field_ptr->value.type->data.pointer.is_const,
15662 field_ptr->value.type->data.pointer.is_volatile,15724 field_ptr->value.type->data.pointer.is_volatile,
15725 PtrLenSingle,
15663 field_ptr_align, 0, 0);15726 field_ptr_align, 0, 0);
15664 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type);15727 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type);
15665 if (type_is_invalid(casted_field_ptr->value.type))15728 if (type_is_invalid(casted_field_ptr->value.type))
...@@ -15668,6 +15731,7 @@ static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,...@@ -15668,6 +15731,7 @@ static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
15668 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, container_type,15731 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, container_type,
15669 casted_field_ptr->value.type->data.pointer.is_const,15732 casted_field_ptr->value.type->data.pointer.is_const,
15670 casted_field_ptr->value.type->data.pointer.is_volatile,15733 casted_field_ptr->value.type->data.pointer.is_volatile,
15734 PtrLenSingle,
15671 parent_ptr_align, 0, 0);15735 parent_ptr_align, 0, 0);
1567215736
15673 if (instr_is_comptime(casted_field_ptr)) {15737 if (instr_is_comptime(casted_field_ptr)) {
...@@ -15983,11 +16047,13 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop...@@ -15983,11 +16047,13 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop
15983 // lib_name: ?[]const u816047 // lib_name: ?[]const u8
15984 ensure_field_index(fn_def_val->type, "lib_name", 6);16048 ensure_field_index(fn_def_val->type, "lib_name", 6);
15985 fn_def_fields[6].special = ConstValSpecialStatic;16049 fn_def_fields[6].special = ConstValSpecialStatic;
15986 fn_def_fields[6].type = get_maybe_type(ira->codegen,16050 TypeTableEntry *u8_ptr = get_pointer_to_type_extra(
15987 get_slice_type(ira->codegen, get_pointer_to_type(ira->codegen,16051 ira->codegen, ira->codegen->builtin_types.entry_u8,
15988 ira->codegen->builtin_types.entry_u8, true)));16052 true, false, PtrLenUnknown,
15989 if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0)16053 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8),
15990 {16054 0, 0);
16055 fn_def_fields[6].type = get_maybe_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
16056 if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) {
15991 fn_def_fields[6].data.x_maybe = create_const_vals(1);16057 fn_def_fields[6].data.x_maybe = create_const_vals(1);
15992 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);16058 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);
15993 init_const_slice(ira->codegen, fn_def_fields[6].data.x_maybe, lib_name, 0, buf_len(fn_node->lib_name), true);16059 init_const_slice(ira->codegen, fn_def_fields[6].data.x_maybe, lib_name, 0, buf_len(fn_node->lib_name), true);
...@@ -16009,8 +16075,8 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop...@@ -16009,8 +16075,8 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop
16009 size_t fn_arg_count = fn_entry->variable_list.length;16075 size_t fn_arg_count = fn_entry->variable_list.length;
16010 ConstExprValue *fn_arg_name_array = create_const_vals(1);16076 ConstExprValue *fn_arg_name_array = create_const_vals(1);
16011 fn_arg_name_array->special = ConstValSpecialStatic;16077 fn_arg_name_array->special = ConstValSpecialStatic;
16012 fn_arg_name_array->type = get_array_type(ira->codegen, get_slice_type(ira->codegen,16078 fn_arg_name_array->type = get_array_type(ira->codegen,
16013 get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true)), fn_arg_count);16079 get_slice_type(ira->codegen, u8_ptr), fn_arg_count);
16014 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;16080 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
16015 fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone;16081 fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone;
16016 fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);16082 fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);
...@@ -17088,7 +17154,8 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi...@@ -17088,7 +17154,8 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
17088 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;17154 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
17089 uint32_t dest_align = (dest_uncasted_type->id == TypeTableEntryIdPointer) ?17155 uint32_t dest_align = (dest_uncasted_type->id == TypeTableEntryIdPointer) ?
17090 dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);17156 dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
17091 TypeTableEntry *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, dest_align, 0, 0);17157 TypeTableEntry *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile,
17158 PtrLenUnknown, dest_align, 0, 0);
1709217159
17093 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr);17160 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr);
17094 if (type_is_invalid(casted_dest_ptr->value.type))17161 if (type_is_invalid(casted_dest_ptr->value.type))
...@@ -17184,8 +17251,10 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi...@@ -17184,8 +17251,10 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
17184 src_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);17251 src_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
1718517252
17186 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;17253 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
17187 TypeTableEntry *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, dest_align, 0, 0);17254 TypeTableEntry *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile,
17188 TypeTableEntry *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, src_align, 0, 0);17255 PtrLenUnknown, dest_align, 0, 0);
17256 TypeTableEntry *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile,
17257 PtrLenUnknown, src_align, 0, 0);
1718917258
17190 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut);17259 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut);
17191 if (type_is_invalid(casted_dest_ptr->value.type))17260 if (type_is_invalid(casted_dest_ptr->value.type))
...@@ -17333,11 +17402,13 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -17333,11 +17402,13 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
17333 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type,17402 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type,
17334 ptr_type->data.pointer.is_const || is_comptime_const,17403 ptr_type->data.pointer.is_const || is_comptime_const,
17335 ptr_type->data.pointer.is_volatile,17404 ptr_type->data.pointer.is_volatile,
17405 PtrLenUnknown,
17336 byte_alignment, 0, 0);17406 byte_alignment, 0, 0);
17337 return_type = get_slice_type(ira->codegen, slice_ptr_type);17407 return_type = get_slice_type(ira->codegen, slice_ptr_type);
17338 } else if (array_type->id == TypeTableEntryIdPointer) {17408 } else if (array_type->id == TypeTableEntryIdPointer) {
17339 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,17409 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,
17340 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,17410 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
17411 PtrLenUnknown,
17341 array_type->data.pointer.alignment, 0, 0);17412 array_type->data.pointer.alignment, 0, 0);
17342 return_type = get_slice_type(ira->codegen, slice_ptr_type);17413 return_type = get_slice_type(ira->codegen, slice_ptr_type);
17343 if (!end) {17414 if (!end) {
...@@ -17774,6 +17845,7 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst...@@ -17774,6 +17845,7 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst
17774 if (result_ptr->value.type->id == TypeTableEntryIdPointer) {17845 if (result_ptr->value.type->id == TypeTableEntryIdPointer) {
17775 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type,17846 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type,
17776 false, result_ptr->value.type->data.pointer.is_volatile,17847 false, result_ptr->value.type->data.pointer.is_volatile,
17848 PtrLenSingle,
17777 result_ptr->value.type->data.pointer.alignment, 0, 0);17849 result_ptr->value.type->data.pointer.alignment, 0, 0);
17778 } else {17850 } else {
17779 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false);17851 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false);
...@@ -17929,6 +18001,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,...@@ -17929,6 +18001,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
17929 TypeTableEntry *payload_type = type_entry->data.error_union.payload_type;18001 TypeTableEntry *payload_type = type_entry->data.error_union.payload_type;
17930 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,18002 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,
17931 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,18003 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
18004 PtrLenSingle,
17932 get_abi_alignment(ira->codegen, payload_type), 0, 0);18005 get_abi_alignment(ira->codegen, payload_type), 0, 0);
17933 if (instr_is_comptime(value)) {18006 if (instr_is_comptime(value)) {
17934 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);18007 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
...@@ -18270,7 +18343,8 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio...@@ -18270,7 +18343,8 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
18270 return ir_unreach_error(ira);18343 return ir_unreach_error(ira);
18271 }18344 }
1827218345
18273 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);18346 TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
18347 true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
18274 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);18348 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
18275 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);18349 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);
18276 if (type_is_invalid(casted_msg->value.type))18350 if (type_is_invalid(casted_msg->value.type))
...@@ -18801,7 +18875,8 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruc...@@ -18801,7 +18875,8 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruc
1880118875
18802 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);18876 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
18803 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,18877 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
18804 instruction->is_const, instruction->is_volatile, align_bytes,18878 instruction->is_const, instruction->is_volatile,
18879 instruction->ptr_len, align_bytes,
18805 instruction->bit_offset_start, instruction->bit_offset_end - instruction->bit_offset_start);18880 instruction->bit_offset_start, instruction->bit_offset_end - instruction->bit_offset_start);
1880618881
18807 return ira->codegen->builtin_types.entry_type;18882 return ira->codegen->builtin_types.entry_type;
src/parser.cpp+1
...@@ -1225,6 +1225,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,...@@ -1225,6 +1225,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
1225 AstNode *child_node = ast_parse_pointer_type(pc, token_index, token);1225 AstNode *child_node = ast_parse_pointer_type(pc, token_index, token);
1226 child_node->column += 1;1226 child_node->column += 1;
1227 AstNode *parent_node = ast_create_node(pc, NodeTypePointerType, token);1227 AstNode *parent_node = ast_create_node(pc, NodeTypePointerType, token);
1228 parent_node->data.pointer_type.star_token = token;
1228 parent_node->data.pointer_type.op_expr = child_node;1229 parent_node->data.pointer_type.op_expr = child_node;
1229 return parent_node;1230 return parent_node;
1230 }1231 }
std/buffer.zig+1-1
...@@ -122,7 +122,7 @@ pub const Buffer = struct {...@@ -122,7 +122,7 @@ pub const Buffer = struct {
122 }122 }
123123
124 /// For passing to C functions.124 /// For passing to C functions.
125 pub fn ptr(self: *const Buffer) *u8 {125 pub fn ptr(self: *const Buffer) [*]u8 {
126 return self.list.items.ptr;126 return self.list.items.ptr;
127 }127 }
128};128};
std/c/darwin.zig+2-2
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1extern "c" fn __error() *c_int;1extern "c" fn __error() *c_int;
2pub extern "c" fn _NSGetExecutablePath(buf: *u8, bufsize: *u32) c_int;2pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;
33
4pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: *u8, buf_len: usize, basep: *i64) usize;4pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize;
55
6pub extern "c" fn mach_absolute_time() u64;6pub extern "c" fn mach_absolute_time() u64;
7pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void;7pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void;
std/c/index.zig+26-24
...@@ -9,6 +9,8 @@ pub use switch (builtin.os) {...@@ -9,6 +9,8 @@ pub use switch (builtin.os) {
9};9};
10const empty_import = @import("../empty.zig");10const empty_import = @import("../empty.zig");
1111
12// TODO https://github.com/ziglang/zig/issues/265 on this whole file
13
12pub extern "c" fn abort() noreturn;14pub extern "c" fn abort() noreturn;
13pub extern "c" fn exit(code: c_int) noreturn;15pub extern "c" fn exit(code: c_int) noreturn;
14pub extern "c" fn isatty(fd: c_int) c_int;16pub extern "c" fn isatty(fd: c_int) c_int;
...@@ -16,45 +18,45 @@ pub extern "c" fn close(fd: c_int) c_int;...@@ -16,45 +18,45 @@ pub extern "c" fn close(fd: c_int) c_int;
16pub extern "c" fn fstat(fd: c_int, buf: *Stat) c_int;18pub extern "c" fn fstat(fd: c_int, buf: *Stat) c_int;
17pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: *Stat) c_int;19pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: *Stat) c_int;
18pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) isize;20pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) isize;
19pub extern "c" fn open(path: *const u8, oflag: c_int, ...) c_int;21pub extern "c" fn open(path: [*]const u8, oflag: c_int, ...) c_int;
20pub extern "c" fn raise(sig: c_int) c_int;22pub extern "c" fn raise(sig: c_int) c_int;
21pub extern "c" fn read(fd: c_int, buf: *c_void, nbyte: usize) isize;23pub extern "c" fn read(fd: c_int, buf: [*]c_void, nbyte: usize) isize;
22pub extern "c" fn stat(noalias path: *const u8, noalias buf: *Stat) c_int;24pub extern "c" fn stat(noalias path: [*]const u8, noalias buf: *Stat) c_int;
23pub extern "c" fn write(fd: c_int, buf: *const c_void, nbyte: usize) isize;25pub extern "c" fn write(fd: c_int, buf: [*]const c_void, nbyte: usize) isize;
24pub extern "c" fn mmap(addr: ?*c_void, len: usize, prot: c_int, flags: c_int, fd: c_int, offset: isize) ?*c_void;26pub extern "c" fn mmap(addr: ?[*]c_void, len: usize, prot: c_int, flags: c_int, fd: c_int, offset: isize) ?[*]c_void;
25pub extern "c" fn munmap(addr: *c_void, len: usize) c_int;27pub extern "c" fn munmap(addr: [*]c_void, len: usize) c_int;
26pub extern "c" fn unlink(path: *const u8) c_int;28pub extern "c" fn unlink(path: [*]const u8) c_int;
27pub extern "c" fn getcwd(buf: *u8, size: usize) ?*u8;29pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
28pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_int, options: c_int) c_int;30pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_int, options: c_int) c_int;
29pub extern "c" fn fork() c_int;31pub extern "c" fn fork() c_int;
30pub extern "c" fn access(path: *const u8, mode: c_uint) c_int;32pub extern "c" fn access(path: [*]const u8, mode: c_uint) c_int;
31pub extern "c" fn pipe(fds: *c_int) c_int;33pub extern "c" fn pipe(fds: *[2]c_int) c_int;
32pub extern "c" fn mkdir(path: *const u8, mode: c_uint) c_int;34pub extern "c" fn mkdir(path: [*]const u8, mode: c_uint) c_int;
33pub extern "c" fn symlink(existing: *const u8, new: *const u8) c_int;35pub extern "c" fn symlink(existing: [*]const u8, new: [*]const u8) c_int;
34pub extern "c" fn rename(old: *const u8, new: *const u8) c_int;36pub extern "c" fn rename(old: [*]const u8, new: [*]const u8) c_int;
35pub extern "c" fn chdir(path: *const u8) c_int;37pub extern "c" fn chdir(path: [*]const u8) c_int;
36pub extern "c" fn execve(path: *const u8, argv: *const ?*const u8, envp: *const ?*const u8) c_int;38pub extern "c" fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) c_int;
37pub extern "c" fn dup(fd: c_int) c_int;39pub extern "c" fn dup(fd: c_int) c_int;
38pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;40pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;
39pub extern "c" fn readlink(noalias path: *const u8, noalias buf: *u8, bufsize: usize) isize;41pub extern "c" fn readlink(noalias path: [*]const u8, noalias buf: [*]u8, bufsize: usize) isize;
40pub extern "c" fn realpath(noalias file_name: *const u8, noalias resolved_name: *u8) ?*u8;42pub extern "c" fn realpath(noalias file_name: [*]const u8, noalias resolved_name: [*]u8) ?[*]u8;
41pub extern "c" fn sigprocmask(how: c_int, noalias set: *const sigset_t, noalias oset: ?*sigset_t) c_int;43pub extern "c" fn sigprocmask(how: c_int, noalias set: *const sigset_t, noalias oset: ?*sigset_t) c_int;
42pub extern "c" fn gettimeofday(tv: ?*timeval, tz: ?*timezone) c_int;44pub extern "c" fn gettimeofday(tv: ?*timeval, tz: ?*timezone) c_int;
43pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int;45pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int;
44pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;46pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;
45pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;47pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;
46pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) c_int;48pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) c_int;
47pub extern "c" fn rmdir(path: *const u8) c_int;49pub extern "c" fn rmdir(path: [*]const u8) c_int;
4850
49pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;51pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?[*]c_void;
50pub extern "c" fn malloc(usize) ?*c_void;52pub extern "c" fn malloc(usize) ?[*]c_void;
51pub extern "c" fn realloc(*c_void, usize) ?*c_void;53pub extern "c" fn realloc([*]c_void, usize) ?[*]c_void;
52pub extern "c" fn free(*c_void) void;54pub extern "c" fn free([*]c_void) void;
53pub extern "c" fn posix_memalign(memptr: **c_void, alignment: usize, size: usize) c_int;55pub extern "c" fn posix_memalign(memptr: *[*]c_void, alignment: usize, size: usize) c_int;
5456
55pub extern "pthread" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: extern fn (?*c_void) ?*c_void, noalias arg: ?*c_void) c_int;57pub extern "pthread" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: extern fn (?*c_void) ?*c_void, noalias arg: ?*c_void) c_int;
56pub extern "pthread" fn pthread_attr_init(attr: *pthread_attr_t) c_int;58pub extern "pthread" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
57pub extern "pthread" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;59pub extern "pthread" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: [*]c_void, stacksize: usize) c_int;
58pub extern "pthread" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;60pub extern "pthread" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
59pub extern "pthread" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;61pub extern "pthread" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;
6062
std/c/linux.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1pub use @import("../os/linux/errno.zig");1pub use @import("../os/linux/errno.zig");
22
3pub extern "c" fn getrandom(buf_ptr: *u8, buf_len: usize, flags: c_uint) c_int;3pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
4extern "c" fn __errno_location() *c_int;4extern "c" fn __errno_location() *c_int;
5pub const _errno = __errno_location;5pub const _errno = __errno_location;
66
std/cstr.zig+5-5
...@@ -57,7 +57,7 @@ pub fn addNullByte(allocator: *mem.Allocator, slice: []const u8) ![]u8 {...@@ -57,7 +57,7 @@ pub fn addNullByte(allocator: *mem.Allocator, slice: []const u8) ![]u8 {
57pub const NullTerminated2DArray = struct {57pub const NullTerminated2DArray = struct {
58 allocator: *mem.Allocator,58 allocator: *mem.Allocator,
59 byte_count: usize,59 byte_count: usize,
60 ptr: ?*?*u8,60 ptr: ?[*]?[*]u8,
6161
62 /// Takes N lists of strings, concatenates the lists together, and adds a null terminator62 /// Takes N lists of strings, concatenates the lists together, and adds a null terminator
63 /// Caller must deinit result63 /// Caller must deinit result
...@@ -79,12 +79,12 @@ pub const NullTerminated2DArray = struct {...@@ -79,12 +79,12 @@ pub const NullTerminated2DArray = struct {
79 errdefer allocator.free(buf);79 errdefer allocator.free(buf);
8080
81 var write_index = index_size;81 var write_index = index_size;
82 const index_buf = ([]?*u8)(buf);82 const index_buf = ([]?[*]u8)(buf);
8383
84 var i: usize = 0;84 var i: usize = 0;
85 for (slices) |slice| {85 for (slices) |slice| {
86 for (slice) |inner| {86 for (slice) |inner| {
87 index_buf[i] = &buf[write_index];87 index_buf[i] = buf.ptr + write_index;
88 i += 1;88 i += 1;
89 mem.copy(u8, buf[write_index..], inner);89 mem.copy(u8, buf[write_index..], inner);
90 write_index += inner.len;90 write_index += inner.len;
...@@ -97,12 +97,12 @@ pub const NullTerminated2DArray = struct {...@@ -97,12 +97,12 @@ pub const NullTerminated2DArray = struct {
97 return NullTerminated2DArray{97 return NullTerminated2DArray{
98 .allocator = allocator,98 .allocator = allocator,
99 .byte_count = byte_count,99 .byte_count = byte_count,
100 .ptr = @ptrCast(?*?*u8, buf.ptr),100 .ptr = @ptrCast(?[*]?[*]u8, buf.ptr),
101 };101 };
102 }102 }
103103
104 pub fn deinit(self: *NullTerminated2DArray) void {104 pub fn deinit(self: *NullTerminated2DArray) void {
105 const buf = @ptrCast(*u8, self.ptr);105 const buf = @ptrCast([*]u8, self.ptr);
106 self.allocator.free(buf[0..self.byte_count]);106 self.allocator.free(buf[0..self.byte_count]);
107 }107 }
108};108};
std/heap.zig+9-9
...@@ -18,11 +18,11 @@ var c_allocator_state = Allocator{...@@ -18,11 +18,11 @@ var c_allocator_state = Allocator{
1818
19fn cAlloc(self: *Allocator, n: usize, alignment: u29) ![]u8 {19fn cAlloc(self: *Allocator, n: usize, alignment: u29) ![]u8 {
20 assert(alignment <= @alignOf(c_longdouble));20 assert(alignment <= @alignOf(c_longdouble));
21 return if (c.malloc(n)) |buf| @ptrCast(*u8, buf)[0..n] else error.OutOfMemory;21 return if (c.malloc(n)) |buf| @ptrCast([*]u8, buf)[0..n] else error.OutOfMemory;
22}22}
2323
24fn cRealloc(self: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {24fn cRealloc(self: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
25 const old_ptr = @ptrCast(*c_void, old_mem.ptr);25 const old_ptr = @ptrCast([*]c_void, old_mem.ptr);
26 if (c.realloc(old_ptr, new_size)) |buf| {26 if (c.realloc(old_ptr, new_size)) |buf| {
27 return @ptrCast(*u8, buf)[0..new_size];27 return @ptrCast(*u8, buf)[0..new_size];
28 } else if (new_size <= old_mem.len) {28 } else if (new_size <= old_mem.len) {
...@@ -33,7 +33,7 @@ fn cRealloc(self: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![...@@ -33,7 +33,7 @@ fn cRealloc(self: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![
33}33}
3434
35fn cFree(self: *Allocator, old_mem: []u8) void {35fn cFree(self: *Allocator, old_mem: []u8) void {
36 const old_ptr = @ptrCast(*c_void, old_mem.ptr);36 const old_ptr = @ptrCast([*]c_void, old_mem.ptr);
37 c.free(old_ptr);37 c.free(old_ptr);
38}38}
3939
...@@ -74,7 +74,7 @@ pub const DirectAllocator = struct {...@@ -74,7 +74,7 @@ pub const DirectAllocator = struct {
74 const addr = p.mmap(null, alloc_size, p.PROT_READ | p.PROT_WRITE, p.MAP_PRIVATE | p.MAP_ANONYMOUS, -1, 0);74 const addr = p.mmap(null, alloc_size, p.PROT_READ | p.PROT_WRITE, p.MAP_PRIVATE | p.MAP_ANONYMOUS, -1, 0);
75 if (addr == p.MAP_FAILED) return error.OutOfMemory;75 if (addr == p.MAP_FAILED) return error.OutOfMemory;
7676
77 if (alloc_size == n) return @intToPtr(*u8, addr)[0..n];77 if (alloc_size == n) return @intToPtr([*]u8, addr)[0..n];
7878
79 var aligned_addr = addr & ~usize(alignment - 1);79 var aligned_addr = addr & ~usize(alignment - 1);
80 aligned_addr += alignment;80 aligned_addr += alignment;
...@@ -93,7 +93,7 @@ pub const DirectAllocator = struct {...@@ -93,7 +93,7 @@ pub const DirectAllocator = struct {
93 //It is impossible that there is an unoccupied page at the top of our93 //It is impossible that there is an unoccupied page at the top of our
94 // mmap.94 // mmap.
9595
96 return @intToPtr(*u8, aligned_addr)[0..n];96 return @intToPtr([*]u8, aligned_addr)[0..n];
97 },97 },
98 Os.windows => {98 Os.windows => {
99 const amt = n + alignment + @sizeOf(usize);99 const amt = n + alignment + @sizeOf(usize);
...@@ -109,7 +109,7 @@ pub const DirectAllocator = struct {...@@ -109,7 +109,7 @@ pub const DirectAllocator = struct {
109 const adjusted_addr = root_addr + march_forward_bytes;109 const adjusted_addr = root_addr + march_forward_bytes;
110 const record_addr = adjusted_addr + n;110 const record_addr = adjusted_addr + n;
111 @intToPtr(*align(1) usize, record_addr).* = root_addr;111 @intToPtr(*align(1) usize, record_addr).* = root_addr;
112 return @intToPtr(*u8, adjusted_addr)[0..n];112 return @intToPtr([*]u8, adjusted_addr)[0..n];
113 },113 },
114 else => @compileError("Unsupported OS"),114 else => @compileError("Unsupported OS"),
115 }115 }
...@@ -140,7 +140,7 @@ pub const DirectAllocator = struct {...@@ -140,7 +140,7 @@ pub const DirectAllocator = struct {
140 const old_adjusted_addr = @ptrToInt(old_mem.ptr);140 const old_adjusted_addr = @ptrToInt(old_mem.ptr);
141 const old_record_addr = old_adjusted_addr + old_mem.len;141 const old_record_addr = old_adjusted_addr + old_mem.len;
142 const root_addr = @intToPtr(*align(1) usize, old_record_addr).*;142 const root_addr = @intToPtr(*align(1) usize, old_record_addr).*;
143 const old_ptr = @intToPtr(os.windows.LPVOID, root_addr);143 const old_ptr = @intToPtr([*]c_void, root_addr);
144 const amt = new_size + alignment + @sizeOf(usize);144 const amt = new_size + alignment + @sizeOf(usize);
145 const new_ptr = os.windows.HeapReAlloc(??self.heap_handle, 0, old_ptr, amt) ?? blk: {145 const new_ptr = os.windows.HeapReAlloc(??self.heap_handle, 0, old_ptr, amt) ?? blk: {
146 if (new_size > old_mem.len) return error.OutOfMemory;146 if (new_size > old_mem.len) return error.OutOfMemory;
...@@ -154,7 +154,7 @@ pub const DirectAllocator = struct {...@@ -154,7 +154,7 @@ pub const DirectAllocator = struct {
154 assert(new_adjusted_addr % alignment == 0);154 assert(new_adjusted_addr % alignment == 0);
155 const new_record_addr = new_adjusted_addr + new_size;155 const new_record_addr = new_adjusted_addr + new_size;
156 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;156 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;
157 return @intToPtr(*u8, new_adjusted_addr)[0..new_size];157 return @intToPtr([*]u8, new_adjusted_addr)[0..new_size];
158 },158 },
159 else => @compileError("Unsupported OS"),159 else => @compileError("Unsupported OS"),
160 }160 }
...@@ -170,7 +170,7 @@ pub const DirectAllocator = struct {...@@ -170,7 +170,7 @@ pub const DirectAllocator = struct {
170 Os.windows => {170 Os.windows => {
171 const record_addr = @ptrToInt(bytes.ptr) + bytes.len;171 const record_addr = @ptrToInt(bytes.ptr) + bytes.len;
172 const root_addr = @intToPtr(*align(1) usize, record_addr).*;172 const root_addr = @intToPtr(*align(1) usize, record_addr).*;
173 const ptr = @intToPtr(os.windows.LPVOID, root_addr);173 const ptr = @intToPtr([*]c_void, root_addr);
174 _ = os.windows.HeapFree(??self.heap_handle, 0, ptr);174 _ = os.windows.HeapFree(??self.heap_handle, 0, ptr);
175 },175 },
176 else => @compileError("Unsupported OS"),176 else => @compileError("Unsupported OS"),
std/os/child_process.zig+1-1
...@@ -639,7 +639,7 @@ pub const ChildProcess = struct {...@@ -639,7 +639,7 @@ pub const ChildProcess = struct {
639 }639 }
640};640};
641641
642fn windowsCreateProcess(app_name: *u8, cmd_line: *u8, envp_ptr: ?*u8, cwd_ptr: ?*u8, lpStartupInfo: *windows.STARTUPINFOA, lpProcessInformation: *windows.PROCESS_INFORMATION) !void {642fn windowsCreateProcess(app_name: [*]u8, cmd_line: [*]u8, envp_ptr: ?[*]u8, cwd_ptr: ?[*]u8, lpStartupInfo: *windows.STARTUPINFOA, lpProcessInformation: *windows.PROCESS_INFORMATION) !void {
643 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0, @ptrCast(?*c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0) {643 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0, @ptrCast(?*c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0) {
644 const err = windows.GetLastError();644 const err = windows.GetLastError();
645 return switch (err) {645 return switch (err) {
std/os/darwin.zig+23-22
...@@ -317,7 +317,8 @@ pub fn lseek(fd: i32, offset: isize, whence: c_int) usize {...@@ -317,7 +317,8 @@ pub fn lseek(fd: i32, offset: isize, whence: c_int) usize {
317 return errnoWrap(c.lseek(fd, offset, whence));317 return errnoWrap(c.lseek(fd, offset, whence));
318}318}
319319
320pub fn open(path: *const u8, flags: u32, mode: usize) usize {320// TODO https://github.com/ziglang/zig/issues/265 on the whole file
321pub fn open(path: [*]const u8, flags: u32, mode: usize) usize {
321 return errnoWrap(c.open(path, @bitCast(c_int, flags), mode));322 return errnoWrap(c.open(path, @bitCast(c_int, flags), mode));
322}323}
323324
...@@ -325,33 +326,33 @@ pub fn raise(sig: i32) usize {...@@ -325,33 +326,33 @@ pub fn raise(sig: i32) usize {
325 return errnoWrap(c.raise(sig));326 return errnoWrap(c.raise(sig));
326}327}
327328
328pub fn read(fd: i32, buf: *u8, nbyte: usize) usize {329pub fn read(fd: i32, buf: [*]u8, nbyte: usize) usize {
329 return errnoWrap(c.read(fd, @ptrCast(*c_void, buf), nbyte));330 return errnoWrap(c.read(fd, @ptrCast([*]c_void, buf), nbyte));
330}331}
331332
332pub fn stat(noalias path: *const u8, noalias buf: *stat) usize {333pub fn stat(noalias path: [*]const u8, noalias buf: *stat) usize {
333 return errnoWrap(c.stat(path, buf));334 return errnoWrap(c.stat(path, buf));
334}335}
335336
336pub fn write(fd: i32, buf: *const u8, nbyte: usize) usize {337pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) usize {
337 return errnoWrap(c.write(fd, @ptrCast(*const c_void, buf), nbyte));338 return errnoWrap(c.write(fd, @ptrCast([*]const c_void, buf), nbyte));
338}339}
339340
340pub fn mmap(address: ?*u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {341pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
341 const ptr_result = c.mmap(@ptrCast(*c_void, address), length, @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);342 const ptr_result = c.mmap(@ptrCast([*]c_void, address), length, @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
342 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));343 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));
343 return errnoWrap(isize_result);344 return errnoWrap(isize_result);
344}345}
345346
346pub fn munmap(address: usize, length: usize) usize {347pub fn munmap(address: usize, length: usize) usize {
347 return errnoWrap(c.munmap(@intToPtr(*c_void, address), length));348 return errnoWrap(c.munmap(@intToPtr([*]c_void, address), length));
348}349}
349350
350pub fn unlink(path: *const u8) usize {351pub fn unlink(path: [*]const u8) usize {
351 return errnoWrap(c.unlink(path));352 return errnoWrap(c.unlink(path));
352}353}
353354
354pub fn getcwd(buf: *u8, size: usize) usize {355pub fn getcwd(buf: [*]u8, size: usize) usize {
355 return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(c._errno().*)) else 0;356 return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(c._errno().*)) else 0;
356}357}
357358
...@@ -364,40 +365,40 @@ pub fn fork() usize {...@@ -364,40 +365,40 @@ pub fn fork() usize {
364 return errnoWrap(c.fork());365 return errnoWrap(c.fork());
365}366}
366367
367pub fn access(path: *const u8, mode: u32) usize {368pub fn access(path: [*]const u8, mode: u32) usize {
368 return errnoWrap(c.access(path, mode));369 return errnoWrap(c.access(path, mode));
369}370}
370371
371pub fn pipe(fds: *[2]i32) usize {372pub fn pipe(fds: *[2]i32) usize {
372 comptime assert(i32.bit_count == c_int.bit_count);373 comptime assert(i32.bit_count == c_int.bit_count);
373 return errnoWrap(c.pipe(@ptrCast(*c_int, fds)));374 return errnoWrap(c.pipe(@ptrCast(*[2]c_int, fds)));
374}375}
375376
376pub fn getdirentries64(fd: i32, buf_ptr: *u8, buf_len: usize, basep: *i64) usize {377pub fn getdirentries64(fd: i32, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize {
377 return errnoWrap(@bitCast(isize, c.__getdirentries64(fd, buf_ptr, buf_len, basep)));378 return errnoWrap(@bitCast(isize, c.__getdirentries64(fd, buf_ptr, buf_len, basep)));
378}379}
379380
380pub fn mkdir(path: *const u8, mode: u32) usize {381pub fn mkdir(path: [*]const u8, mode: u32) usize {
381 return errnoWrap(c.mkdir(path, mode));382 return errnoWrap(c.mkdir(path, mode));
382}383}
383384
384pub fn symlink(existing: *const u8, new: *const u8) usize {385pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
385 return errnoWrap(c.symlink(existing, new));386 return errnoWrap(c.symlink(existing, new));
386}387}
387388
388pub fn rename(old: *const u8, new: *const u8) usize {389pub fn rename(old: [*]const u8, new: [*]const u8) usize {
389 return errnoWrap(c.rename(old, new));390 return errnoWrap(c.rename(old, new));
390}391}
391392
392pub fn rmdir(path: *const u8) usize {393pub fn rmdir(path: [*]const u8) usize {
393 return errnoWrap(c.rmdir(path));394 return errnoWrap(c.rmdir(path));
394}395}
395396
396pub fn chdir(path: *const u8) usize {397pub fn chdir(path: [*]const u8) usize {
397 return errnoWrap(c.chdir(path));398 return errnoWrap(c.chdir(path));
398}399}
399400
400pub fn execve(path: *const u8, argv: *const ?*const u8, envp: *const ?*const u8) usize {401pub fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) usize {
401 return errnoWrap(c.execve(path, argv, envp));402 return errnoWrap(c.execve(path, argv, envp));
402}403}
403404
...@@ -405,7 +406,7 @@ pub fn dup2(old: i32, new: i32) usize {...@@ -405,7 +406,7 @@ pub fn dup2(old: i32, new: i32) usize {
405 return errnoWrap(c.dup2(old, new));406 return errnoWrap(c.dup2(old, new));
406}407}
407408
408pub fn readlink(noalias path: *const u8, noalias buf_ptr: *u8, buf_len: usize) usize {409pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
409 return errnoWrap(c.readlink(path, buf_ptr, buf_len));410 return errnoWrap(c.readlink(path, buf_ptr, buf_len));
410}411}
411412
...@@ -417,7 +418,7 @@ pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {...@@ -417,7 +418,7 @@ pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {
417 return errnoWrap(c.nanosleep(req, rem));418 return errnoWrap(c.nanosleep(req, rem));
418}419}
419420
420pub fn realpath(noalias filename: *const u8, noalias resolved_name: *u8) usize {421pub fn realpath(noalias filename: [*]const u8, noalias resolved_name: [*]u8) usize {
421 return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(c._errno().*)) else 0;422 return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(c._errno().*)) else 0;
422}423}
423424
std/os/file.zig+2-2
...@@ -313,7 +313,7 @@ pub const File = struct {...@@ -313,7 +313,7 @@ pub const File = struct {
313 if (is_posix) {313 if (is_posix) {
314 var index: usize = 0;314 var index: usize = 0;
315 while (index < buffer.len) {315 while (index < buffer.len) {
316 const amt_read = posix.read(self.handle, &buffer[index], buffer.len - index);316 const amt_read = posix.read(self.handle, buffer.ptr + index, buffer.len - index);
317 const read_err = posix.getErrno(amt_read);317 const read_err = posix.getErrno(amt_read);
318 if (read_err > 0) {318 if (read_err > 0) {
319 switch (read_err) {319 switch (read_err) {
...@@ -334,7 +334,7 @@ pub const File = struct {...@@ -334,7 +334,7 @@ pub const File = struct {
334 while (index < buffer.len) {334 while (index < buffer.len) {
335 const want_read_count = windows.DWORD(math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index));335 const want_read_count = windows.DWORD(math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index));
336 var amt_read: windows.DWORD = undefined;336 var amt_read: windows.DWORD = undefined;
337 if (windows.ReadFile(self.handle, @ptrCast(*c_void, &buffer[index]), want_read_count, &amt_read, null) == 0) {337 if (windows.ReadFile(self.handle, @ptrCast([*]c_void, buffer.ptr + index), want_read_count, &amt_read, null) == 0) {
338 const err = windows.GetLastError();338 const err = windows.GetLastError();
339 return switch (err) {339 return switch (err) {
340 windows.ERROR.OPERATION_ABORTED => continue,340 windows.ERROR.OPERATION_ABORTED => continue,
std/os/index.zig+31-70
...@@ -134,20 +134,7 @@ pub fn getRandomBytes(buf: []u8) !void {...@@ -134,20 +134,7 @@ pub fn getRandomBytes(buf: []u8) !void {
134 }134 }
135 },135 },
136 Os.zen => {136 Os.zen => {
137 const randomness = []u8{137 const randomness = []u8{ 42, 1, 7, 12, 22, 17, 99, 16, 26, 87, 41, 45 };
138 42,
139 1,
140 7,
141 12,
142 22,
143 17,
144 99,
145 16,
146 26,
147 87,
148 41,
149 45,
150 };
151 var i: usize = 0;138 var i: usize = 0;
152 while (i < buf.len) : (i += 1) {139 while (i < buf.len) : (i += 1) {
153 if (i > randomness.len) return error.Unknown;140 if (i > randomness.len) return error.Unknown;
...@@ -238,7 +225,7 @@ pub fn posixRead(fd: i32, buf: []u8) !void {...@@ -238,7 +225,7 @@ pub fn posixRead(fd: i32, buf: []u8) !void {
238 var index: usize = 0;225 var index: usize = 0;
239 while (index < buf.len) {226 while (index < buf.len) {
240 const want_to_read = math.min(buf.len - index, usize(max_buf_len));227 const want_to_read = math.min(buf.len - index, usize(max_buf_len));
241 const rc = posix.read(fd, &buf[index], want_to_read);228 const rc = posix.read(fd, buf.ptr + index, want_to_read);
242 const err = posix.getErrno(rc);229 const err = posix.getErrno(rc);
243 if (err > 0) {230 if (err > 0) {
244 return switch (err) {231 return switch (err) {
...@@ -278,7 +265,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {...@@ -278,7 +265,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {
278 var index: usize = 0;265 var index: usize = 0;
279 while (index < bytes.len) {266 while (index < bytes.len) {
280 const amt_to_write = math.min(bytes.len - index, usize(max_bytes_len));267 const amt_to_write = math.min(bytes.len - index, usize(max_bytes_len));
281 const rc = posix.write(fd, &bytes[index], amt_to_write);268 const rc = posix.write(fd, bytes.ptr + index, amt_to_write);
282 const write_err = posix.getErrno(rc);269 const write_err = posix.getErrno(rc);
283 if (write_err > 0) {270 if (write_err > 0) {
284 return switch (write_err) {271 return switch (write_err) {
...@@ -328,7 +315,8 @@ pub fn posixOpen(allocator: *Allocator, file_path: []const u8, flags: u32, perm:...@@ -328,7 +315,8 @@ pub fn posixOpen(allocator: *Allocator, file_path: []const u8, flags: u32, perm:
328 return posixOpenC(path_with_null.ptr, flags, perm);315 return posixOpenC(path_with_null.ptr, flags, perm);
329}316}
330317
331pub fn posixOpenC(file_path: *const u8, flags: u32, perm: usize) !i32 {318// TODO https://github.com/ziglang/zig/issues/265
319pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 {
332 while (true) {320 while (true) {
333 const result = posix.open(file_path, flags, perm);321 const result = posix.open(file_path, flags, perm);
334 const err = posix.getErrno(result);322 const err = posix.getErrno(result);
...@@ -374,19 +362,19 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) !void {...@@ -374,19 +362,19 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) !void {
374 }362 }
375}363}
376364
377pub fn createNullDelimitedEnvMap(allocator: *Allocator, env_map: *const BufMap) ![]?*u8 {365pub fn createNullDelimitedEnvMap(allocator: *Allocator, env_map: *const BufMap) ![]?[*]u8 {
378 const envp_count = env_map.count();366 const envp_count = env_map.count();
379 const envp_buf = try allocator.alloc(?*u8, envp_count + 1);367 const envp_buf = try allocator.alloc(?[*]u8, envp_count + 1);
380 mem.set(?*u8, envp_buf, null);368 mem.set(?[*]u8, envp_buf, null);
381 errdefer freeNullDelimitedEnvMap(allocator, envp_buf);369 errdefer freeNullDelimitedEnvMap(allocator, envp_buf);
382 {370 {
383 var it = env_map.iterator();371 var it = env_map.iterator();
384 var i: usize = 0;372 var i: usize = 0;
385 while (it.next()) |pair| : (i += 1) {373 while (it.next()) |pair| : (i += 1) {
386 const env_buf = try allocator.alloc(u8, pair.key.len + pair.value.len + 2);374 const env_buf = try allocator.alloc(u8, pair.key.len + pair.value.len + 2);
387 @memcpy(&env_buf[0], pair.key.ptr, pair.key.len);375 @memcpy(env_buf.ptr, pair.key.ptr, pair.key.len);
388 env_buf[pair.key.len] = '=';376 env_buf[pair.key.len] = '=';
389 @memcpy(&env_buf[pair.key.len + 1], pair.value.ptr, pair.value.len);377 @memcpy(env_buf.ptr + pair.key.len + 1, pair.value.ptr, pair.value.len);
390 env_buf[env_buf.len - 1] = 0;378 env_buf[env_buf.len - 1] = 0;
391379
392 envp_buf[i] = env_buf.ptr;380 envp_buf[i] = env_buf.ptr;
...@@ -397,7 +385,7 @@ pub fn createNullDelimitedEnvMap(allocator: *Allocator, env_map: *const BufMap)...@@ -397,7 +385,7 @@ pub fn createNullDelimitedEnvMap(allocator: *Allocator, env_map: *const BufMap)
397 return envp_buf;385 return envp_buf;
398}386}
399387
400pub fn freeNullDelimitedEnvMap(allocator: *Allocator, envp_buf: []?*u8) void {388pub fn freeNullDelimitedEnvMap(allocator: *Allocator, envp_buf: []?[*]u8) void {
401 for (envp_buf) |env| {389 for (envp_buf) |env| {
402 const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;390 const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;
403 allocator.free(env_buf);391 allocator.free(env_buf);
...@@ -411,8 +399,8 @@ pub fn freeNullDelimitedEnvMap(allocator: *Allocator, envp_buf: []?*u8) void {...@@ -411,8 +399,8 @@ pub fn freeNullDelimitedEnvMap(allocator: *Allocator, envp_buf: []?*u8) void {
411/// `argv[0]` is the executable path.399/// `argv[0]` is the executable path.
412/// This function also uses the PATH environment variable to get the full path to the executable.400/// This function also uses the PATH environment variable to get the full path to the executable.
413pub fn posixExecve(argv: []const []const u8, env_map: *const BufMap, allocator: *Allocator) !void {401pub fn posixExecve(argv: []const []const u8, env_map: *const BufMap, allocator: *Allocator) !void {
414 const argv_buf = try allocator.alloc(?*u8, argv.len + 1);402 const argv_buf = try allocator.alloc(?[*]u8, argv.len + 1);
415 mem.set(?*u8, argv_buf, null);403 mem.set(?[*]u8, argv_buf, null);
416 defer {404 defer {
417 for (argv_buf) |arg| {405 for (argv_buf) |arg| {
418 const arg_buf = if (arg) |ptr| cstr.toSlice(ptr) else break;406 const arg_buf = if (arg) |ptr| cstr.toSlice(ptr) else break;
...@@ -422,7 +410,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: *const BufMap, allocator:...@@ -422,7 +410,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: *const BufMap, allocator:
422 }410 }
423 for (argv) |arg, i| {411 for (argv) |arg, i| {
424 const arg_buf = try allocator.alloc(u8, arg.len + 1);412 const arg_buf = try allocator.alloc(u8, arg.len + 1);
425 @memcpy(&arg_buf[0], arg.ptr, arg.len);413 @memcpy(arg_buf.ptr, arg.ptr, arg.len);
426 arg_buf[arg.len] = 0;414 arg_buf[arg.len] = 0;
427415
428 argv_buf[i] = arg_buf.ptr;416 argv_buf[i] = arg_buf.ptr;
...@@ -494,7 +482,7 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {...@@ -494,7 +482,7 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
494}482}
495483
496pub var linux_aux_raw = []usize{0} ** 38;484pub var linux_aux_raw = []usize{0} ** 38;
497pub var posix_environ_raw: []*u8 = undefined;485pub var posix_environ_raw: [][*]u8 = undefined;
498486
499/// Caller must free result when done.487/// Caller must free result when done.
500pub fn getEnvMap(allocator: *Allocator) !BufMap {488pub fn getEnvMap(allocator: *Allocator) !BufMap {
...@@ -1311,7 +1299,7 @@ pub const Dir = struct {...@@ -1311,7 +1299,7 @@ pub const Dir = struct {
1311 const next_index = self.index + linux_entry.d_reclen;1299 const next_index = self.index + linux_entry.d_reclen;
1312 self.index = next_index;1300 self.index = next_index;
13131301
1314 const name = cstr.toSlice(&linux_entry.d_name);1302 const name = cstr.toSlice(@ptrCast([*]u8, &linux_entry.d_name));
13151303
1316 // skip . and .. entries1304 // skip . and .. entries
1317 if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) {1305 if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) {
...@@ -1485,12 +1473,12 @@ pub const ArgIteratorPosix = struct {...@@ -1485,12 +1473,12 @@ pub const ArgIteratorPosix = struct {
14851473
1486 /// This is marked as public but actually it's only meant to be used1474 /// This is marked as public but actually it's only meant to be used
1487 /// internally by zig's startup code.1475 /// internally by zig's startup code.
1488 pub var raw: []*u8 = undefined;1476 pub var raw: [][*]u8 = undefined;
1489};1477};
14901478
1491pub const ArgIteratorWindows = struct {1479pub const ArgIteratorWindows = struct {
1492 index: usize,1480 index: usize,
1493 cmd_line: *const u8,1481 cmd_line: [*]const u8,
1494 in_quote: bool,1482 in_quote: bool,
1495 quote_count: usize,1483 quote_count: usize,
1496 seen_quote_count: usize,1484 seen_quote_count: usize,
...@@ -1501,7 +1489,7 @@ pub const ArgIteratorWindows = struct {...@@ -1501,7 +1489,7 @@ pub const ArgIteratorWindows = struct {
1501 return initWithCmdLine(windows.GetCommandLineA());1489 return initWithCmdLine(windows.GetCommandLineA());
1502 }1490 }
15031491
1504 pub fn initWithCmdLine(cmd_line: *const u8) ArgIteratorWindows {1492 pub fn initWithCmdLine(cmd_line: [*]const u8) ArgIteratorWindows {
1505 return ArgIteratorWindows{1493 return ArgIteratorWindows{
1506 .index = 0,1494 .index = 0,
1507 .cmd_line = cmd_line,1495 .cmd_line = cmd_line,
...@@ -1616,7 +1604,7 @@ pub const ArgIteratorWindows = struct {...@@ -1616,7 +1604,7 @@ pub const ArgIteratorWindows = struct {
1616 }1604 }
1617 }1605 }
16181606
1619 fn countQuotes(cmd_line: *const u8) usize {1607 fn countQuotes(cmd_line: [*]const u8) usize {
1620 var result: usize = 0;1608 var result: usize = 0;
1621 var backslash_count: usize = 0;1609 var backslash_count: usize = 0;
1622 var index: usize = 0;1610 var index: usize = 0;
...@@ -1722,39 +1710,12 @@ pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {...@@ -1722,39 +1710,12 @@ pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {
1722}1710}
17231711
1724test "windows arg parsing" {1712test "windows arg parsing" {
1725 testWindowsCmdLine(c"a b\tc d", [][]const u8{1713 testWindowsCmdLine(c"a b\tc d", [][]const u8{ "a", "b", "c", "d" });
1726 "a",1714 testWindowsCmdLine(c"\"abc\" d e", [][]const u8{ "abc", "d", "e" });
1727 "b",1715 testWindowsCmdLine(c"a\\\\\\b d\"e f\"g h", [][]const u8{ "a\\\\\\b", "de fg", "h" });
1728 "c",1716 testWindowsCmdLine(c"a\\\\\\\"b c d", [][]const u8{ "a\\\"b", "c", "d" });
1729 "d",1717 testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8{ "a\\\\b c", "d", "e" });
1730 });1718 testWindowsCmdLine(c"a b\tc \"d f", [][]const u8{ "a", "b", "c", "\"d", "f" });
1731 testWindowsCmdLine(c"\"abc\" d e", [][]const u8{
1732 "abc",
1733 "d",
1734 "e",
1735 });
1736 testWindowsCmdLine(c"a\\\\\\b d\"e f\"g h", [][]const u8{
1737 "a\\\\\\b",
1738 "de fg",
1739 "h",
1740 });
1741 testWindowsCmdLine(c"a\\\\\\\"b c d", [][]const u8{
1742 "a\\\"b",
1743 "c",
1744 "d",
1745 });
1746 testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8{
1747 "a\\\\b c",
1748 "d",
1749 "e",
1750 });
1751 testWindowsCmdLine(c"a b\tc \"d f", [][]const u8{
1752 "a",
1753 "b",
1754 "c",
1755 "\"d",
1756 "f",
1757 });
17581719
1759 testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [][]const u8{1720 testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [][]const u8{
1760 ".\\..\\zig-cache\\build",1721 ".\\..\\zig-cache\\build",
...@@ -1765,7 +1726,7 @@ test "windows arg parsing" {...@@ -1765,7 +1726,7 @@ test "windows arg parsing" {
1765 });1726 });
1766}1727}
17671728
1768fn testWindowsCmdLine(input_cmd_line: *const u8, expected_args: []const []const u8) void {1729fn testWindowsCmdLine(input_cmd_line: [*]const u8, expected_args: []const []const u8) void {
1769 var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);1730 var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);
1770 for (expected_args) |expected_arg| {1731 for (expected_args) |expected_arg| {
1771 const arg = ??it.next(debug.global_allocator) catch unreachable;1732 const arg = ??it.next(debug.global_allocator) catch unreachable;
...@@ -2350,7 +2311,7 @@ pub fn posixConnectAsync(sockfd: i32, sockaddr: *const posix.sockaddr) PosixConn...@@ -2350,7 +2311,7 @@ pub fn posixConnectAsync(sockfd: i32, sockaddr: *const posix.sockaddr) PosixConn
2350pub fn posixGetSockOptConnectError(sockfd: i32) PosixConnectError!void {2311pub fn posixGetSockOptConnectError(sockfd: i32) PosixConnectError!void {
2351 var err_code: i32 = undefined;2312 var err_code: i32 = undefined;
2352 var size: u32 = @sizeOf(i32);2313 var size: u32 = @sizeOf(i32);
2353 const rc = posix.getsockopt(sockfd, posix.SOL_SOCKET, posix.SO_ERROR, @ptrCast(*u8, &err_code), &size);2314 const rc = posix.getsockopt(sockfd, posix.SOL_SOCKET, posix.SO_ERROR, @ptrCast([*]u8, &err_code), &size);
2354 assert(size == 4);2315 assert(size == 4);
2355 const err = posix.getErrno(rc);2316 const err = posix.getErrno(rc);
2356 switch (err) {2317 switch (err) {
...@@ -2401,7 +2362,7 @@ pub const Thread = struct {...@@ -2401,7 +2362,7 @@ pub const Thread = struct {
2401 },2362 },
2402 builtin.Os.windows => struct {2363 builtin.Os.windows => struct {
2403 handle: windows.HANDLE,2364 handle: windows.HANDLE,
2404 alloc_start: *c_void,2365 alloc_start: [*]c_void,
2405 heap_handle: windows.HANDLE,2366 heap_handle: windows.HANDLE,
2406 },2367 },
2407 else => @compileError("Unsupported OS"),2368 else => @compileError("Unsupported OS"),
...@@ -2500,7 +2461,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread...@@ -2500,7 +2461,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
2500 const byte_count = @alignOf(WinThread.OuterContext) + @sizeOf(WinThread.OuterContext);2461 const byte_count = @alignOf(WinThread.OuterContext) + @sizeOf(WinThread.OuterContext);
2501 const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) ?? return SpawnThreadError.OutOfMemory;2462 const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) ?? return SpawnThreadError.OutOfMemory;
2502 errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);2463 errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);
2503 const bytes = @ptrCast(*u8, bytes_ptr)[0..byte_count];2464 const bytes = @ptrCast([*]u8, bytes_ptr)[0..byte_count];
2504 const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext) catch unreachable;2465 const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext) catch unreachable;
2505 outer_context.inner = context;2466 outer_context.inner = context;
2506 outer_context.thread.data.heap_handle = heap_handle;2467 outer_context.thread.data.heap_handle = heap_handle;
...@@ -2572,7 +2533,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread...@@ -2572,7 +2533,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
25722533
2573 // align to page2534 // align to page
2574 stack_end -= stack_end % os.page_size;2535 stack_end -= stack_end % os.page_size;
2575 assert(c.pthread_attr_setstack(&attr, @intToPtr(*c_void, stack_addr), stack_end - stack_addr) == 0);2536 assert(c.pthread_attr_setstack(&attr, @intToPtr([*]c_void, stack_addr), stack_end - stack_addr) == 0);
25762537
2577 const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));2538 const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));
2578 switch (err) {2539 switch (err) {
std/os/linux/index.zig+76-47
...@@ -665,15 +665,18 @@ pub fn dup2(old: i32, new: i32) usize {...@@ -665,15 +665,18 @@ pub fn dup2(old: i32, new: i32) usize {
665 return syscall2(SYS_dup2, usize(old), usize(new));665 return syscall2(SYS_dup2, usize(old), usize(new));
666}666}
667667
668pub fn chdir(path: *const u8) usize {668// TODO https://github.com/ziglang/zig/issues/265
669pub fn chdir(path: [*]const u8) usize {
669 return syscall1(SYS_chdir, @ptrToInt(path));670 return syscall1(SYS_chdir, @ptrToInt(path));
670}671}
671672
672pub fn chroot(path: *const u8) usize {673// TODO https://github.com/ziglang/zig/issues/265
674pub fn chroot(path: [*]const u8) usize {
673 return syscall1(SYS_chroot, @ptrToInt(path));675 return syscall1(SYS_chroot, @ptrToInt(path));
674}676}
675677
676pub fn execve(path: *const u8, argv: *const ?*const u8, envp: *const ?*const u8) usize {678// TODO https://github.com/ziglang/zig/issues/265
679pub fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) usize {
677 return syscall3(SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp));680 return syscall3(SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp));
678}681}
679682
...@@ -685,11 +688,11 @@ pub fn futex_wait(uaddr: usize, futex_op: u32, val: i32, timeout: ?*timespec) us...@@ -685,11 +688,11 @@ pub fn futex_wait(uaddr: usize, futex_op: u32, val: i32, timeout: ?*timespec) us
685 return syscall4(SYS_futex, uaddr, futex_op, @bitCast(u32, val), @ptrToInt(timeout));688 return syscall4(SYS_futex, uaddr, futex_op, @bitCast(u32, val), @ptrToInt(timeout));
686}689}
687690
688pub fn getcwd(buf: *u8, size: usize) usize {691pub fn getcwd(buf: [*]u8, size: usize) usize {
689 return syscall2(SYS_getcwd, @ptrToInt(buf), size);692 return syscall2(SYS_getcwd, @ptrToInt(buf), size);
690}693}
691694
692pub fn getdents(fd: i32, dirp: *u8, count: usize) usize {695pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {
693 return syscall3(SYS_getdents, usize(fd), @ptrToInt(dirp), count);696 return syscall3(SYS_getdents, usize(fd), @ptrToInt(dirp), count);
694}697}
695698
...@@ -698,27 +701,32 @@ pub fn isatty(fd: i32) bool {...@@ -698,27 +701,32 @@ pub fn isatty(fd: i32) bool {
698 return syscall3(SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;701 return syscall3(SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
699}702}
700703
701pub fn readlink(noalias path: *const u8, noalias buf_ptr: *u8, buf_len: usize) usize {704// TODO https://github.com/ziglang/zig/issues/265
705pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
702 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);706 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
703}707}
704708
705pub fn mkdir(path: *const u8, mode: u32) usize {709// TODO https://github.com/ziglang/zig/issues/265
710pub fn mkdir(path: [*]const u8, mode: u32) usize {
706 return syscall2(SYS_mkdir, @ptrToInt(path), mode);711 return syscall2(SYS_mkdir, @ptrToInt(path), mode);
707}712}
708713
709pub fn mount(special: *const u8, dir: *const u8, fstype: *const u8, flags: usize, data: usize) usize {714// TODO https://github.com/ziglang/zig/issues/265
715pub fn mount(special: [*]const u8, dir: [*]const u8, fstype: [*]const u8, flags: usize, data: usize) usize {
710 return syscall5(SYS_mount, @ptrToInt(special), @ptrToInt(dir), @ptrToInt(fstype), flags, data);716 return syscall5(SYS_mount, @ptrToInt(special), @ptrToInt(dir), @ptrToInt(fstype), flags, data);
711}717}
712718
713pub fn umount(special: *const u8) usize {719// TODO https://github.com/ziglang/zig/issues/265
720pub fn umount(special: [*]const u8) usize {
714 return syscall2(SYS_umount2, @ptrToInt(special), 0);721 return syscall2(SYS_umount2, @ptrToInt(special), 0);
715}722}
716723
717pub fn umount2(special: *const u8, flags: u32) usize {724// TODO https://github.com/ziglang/zig/issues/265
725pub fn umount2(special: [*]const u8, flags: u32) usize {
718 return syscall2(SYS_umount2, @ptrToInt(special), flags);726 return syscall2(SYS_umount2, @ptrToInt(special), flags);
719}727}
720728
721pub fn mmap(address: ?*u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {729pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
722 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), @bitCast(usize, offset));730 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), @bitCast(usize, offset));
723}731}
724732
...@@ -726,23 +734,26 @@ pub fn munmap(address: usize, length: usize) usize {...@@ -726,23 +734,26 @@ pub fn munmap(address: usize, length: usize) usize {
726 return syscall2(SYS_munmap, address, length);734 return syscall2(SYS_munmap, address, length);
727}735}
728736
729pub fn read(fd: i32, buf: *u8, count: usize) usize {737pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
730 return syscall3(SYS_read, usize(fd), @ptrToInt(buf), count);738 return syscall3(SYS_read, usize(fd), @ptrToInt(buf), count);
731}739}
732740
733pub fn rmdir(path: *const u8) usize {741// TODO https://github.com/ziglang/zig/issues/265
742pub fn rmdir(path: [*]const u8) usize {
734 return syscall1(SYS_rmdir, @ptrToInt(path));743 return syscall1(SYS_rmdir, @ptrToInt(path));
735}744}
736745
737pub fn symlink(existing: *const u8, new: *const u8) usize {746// TODO https://github.com/ziglang/zig/issues/265
747pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
738 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));748 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
739}749}
740750
741pub fn pread(fd: i32, buf: *u8, count: usize, offset: usize) usize {751pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
742 return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset);752 return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset);
743}753}
744754
745pub fn access(path: *const u8, mode: u32) usize {755// TODO https://github.com/ziglang/zig/issues/265
756pub fn access(path: [*]const u8, mode: u32) usize {
746 return syscall2(SYS_access, @ptrToInt(path), mode);757 return syscall2(SYS_access, @ptrToInt(path), mode);
747}758}
748759
...@@ -754,27 +765,31 @@ pub fn pipe2(fd: *[2]i32, flags: usize) usize {...@@ -754,27 +765,31 @@ pub fn pipe2(fd: *[2]i32, flags: usize) usize {
754 return syscall2(SYS_pipe2, @ptrToInt(fd), flags);765 return syscall2(SYS_pipe2, @ptrToInt(fd), flags);
755}766}
756767
757pub fn write(fd: i32, buf: *const u8, count: usize) usize {768pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
758 return syscall3(SYS_write, usize(fd), @ptrToInt(buf), count);769 return syscall3(SYS_write, usize(fd), @ptrToInt(buf), count);
759}770}
760771
761pub fn pwrite(fd: i32, buf: *const u8, count: usize, offset: usize) usize {772pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
762 return syscall4(SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset);773 return syscall4(SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset);
763}774}
764775
765pub fn rename(old: *const u8, new: *const u8) usize {776// TODO https://github.com/ziglang/zig/issues/265
777pub fn rename(old: [*]const u8, new: [*]const u8) usize {
766 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));778 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
767}779}
768780
769pub fn open(path: *const u8, flags: u32, perm: usize) usize {781// TODO https://github.com/ziglang/zig/issues/265
782pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {
770 return syscall3(SYS_open, @ptrToInt(path), flags, perm);783 return syscall3(SYS_open, @ptrToInt(path), flags, perm);
771}784}
772785
773pub fn create(path: *const u8, perm: usize) usize {786// TODO https://github.com/ziglang/zig/issues/265
787pub fn create(path: [*]const u8, perm: usize) usize {
774 return syscall2(SYS_creat, @ptrToInt(path), perm);788 return syscall2(SYS_creat, @ptrToInt(path), perm);
775}789}
776790
777pub fn openat(dirfd: i32, path: *const u8, flags: usize, mode: usize) usize {791// TODO https://github.com/ziglang/zig/issues/265
792pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize {
778 return syscall4(SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode);793 return syscall4(SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode);
779}794}
780795
...@@ -801,7 +816,7 @@ pub fn exit(status: i32) noreturn {...@@ -801,7 +816,7 @@ pub fn exit(status: i32) noreturn {
801 unreachable;816 unreachable;
802}817}
803818
804pub fn getrandom(buf: *u8, count: usize, flags: u32) usize {819pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
805 return syscall3(SYS_getrandom, @ptrToInt(buf), count, usize(flags));820 return syscall3(SYS_getrandom, @ptrToInt(buf), count, usize(flags));
806}821}
807822
...@@ -809,7 +824,8 @@ pub fn kill(pid: i32, sig: i32) usize {...@@ -809,7 +824,8 @@ pub fn kill(pid: i32, sig: i32) usize {
809 return syscall2(SYS_kill, @bitCast(usize, isize(pid)), usize(sig));824 return syscall2(SYS_kill, @bitCast(usize, isize(pid)), usize(sig));
810}825}
811826
812pub fn unlink(path: *const u8) usize {827// TODO https://github.com/ziglang/zig/issues/265
828pub fn unlink(path: [*]const u8) usize {
813 return syscall1(SYS_unlink, @ptrToInt(path));829 return syscall1(SYS_unlink, @ptrToInt(path));
814}830}
815831
...@@ -942,8 +958,8 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti...@@ -942,8 +958,8 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
942 .restorer = @ptrCast(extern fn () void, restore_rt),958 .restorer = @ptrCast(extern fn () void, restore_rt),
943 };959 };
944 var ksa_old: k_sigaction = undefined;960 var ksa_old: k_sigaction = undefined;
945 @memcpy(@ptrCast(*u8, *ksa.mask), @ptrCast(*const u8, *act.mask), 8);961 @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &act.mask), 8);
946 const result = syscall4(SYS_rt_sigaction, sig, @ptrToInt(*ksa), @ptrToInt(*ksa_old), @sizeOf(@typeOf(ksa.mask)));962 const result = syscall4(SYS_rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), @sizeOf(@typeOf(ksa.mask)));
947 const err = getErrno(result);963 const err = getErrno(result);
948 if (err != 0) {964 if (err != 0) {
949 return result;965 return result;
...@@ -951,7 +967,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti...@@ -951,7 +967,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
951 if (oact) |old| {967 if (oact) |old| {
952 old.handler = ksa_old.handler;968 old.handler = ksa_old.handler;
953 old.flags = @truncate(u32, ksa_old.flags);969 old.flags = @truncate(u32, ksa_old.flags);
954 @memcpy(@ptrCast(*u8, *old.mask), @ptrCast(*const u8, *ksa_old.mask), @sizeOf(@typeOf(ksa_old.mask)));970 @memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &ksa_old.mask), @sizeOf(@typeOf(ksa_old.mask)));
955 }971 }
956 return 0;972 return 0;
957}973}
...@@ -1036,7 +1052,7 @@ pub const sockaddr_in6 = extern struct {...@@ -1036,7 +1052,7 @@ pub const sockaddr_in6 = extern struct {
1036};1052};
10371053
1038pub const iovec = extern struct {1054pub const iovec = extern struct {
1039 iov_base: *u8,1055 iov_base: [*]u8,
1040 iov_len: usize,1056 iov_len: usize,
1041};1057};
10421058
...@@ -1052,11 +1068,11 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {...@@ -1052,11 +1068,11 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
1052 return syscall3(SYS_socket, domain, socket_type, protocol);1068 return syscall3(SYS_socket, domain, socket_type, protocol);
1053}1069}
10541070
1055pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: *const u8, optlen: socklen_t) usize {1071pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
1056 return syscall5(SYS_setsockopt, usize(fd), level, optname, usize(optval), @ptrToInt(optlen));1072 return syscall5(SYS_setsockopt, usize(fd), level, optname, usize(optval), @ptrToInt(optlen));
1057}1073}
10581074
1059pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: *u8, noalias optlen: *socklen_t) usize {1075pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
1060 return syscall5(SYS_getsockopt, usize(fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen));1076 return syscall5(SYS_getsockopt, usize(fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
1061}1077}
10621078
...@@ -1072,7 +1088,7 @@ pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {...@@ -1072,7 +1088,7 @@ pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
1072 return syscall3(SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);1088 return syscall3(SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);
1073}1089}
10741090
1075pub fn recvfrom(fd: i32, noalias buf: *u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {1091pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {
1076 return syscall6(SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));1092 return syscall6(SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
1077}1093}
10781094
...@@ -1088,7 +1104,7 @@ pub fn listen(fd: i32, backlog: u32) usize {...@@ -1088,7 +1104,7 @@ pub fn listen(fd: i32, backlog: u32) usize {
1088 return syscall2(SYS_listen, usize(fd), backlog);1104 return syscall2(SYS_listen, usize(fd), backlog);
1089}1105}
10901106
1091pub fn sendto(fd: i32, buf: *const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {1107pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
1092 return syscall6(SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen));1108 return syscall6(SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen));
1093}1109}
10941110
...@@ -1108,59 +1124,72 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize {...@@ -1108,59 +1124,72 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize {
1108 return syscall2(SYS_fstat, usize(fd), @ptrToInt(stat_buf));1124 return syscall2(SYS_fstat, usize(fd), @ptrToInt(stat_buf));
1109}1125}
11101126
1111pub fn stat(pathname: *const u8, statbuf: *Stat) usize {1127// TODO https://github.com/ziglang/zig/issues/265
1128pub fn stat(pathname: [*]const u8, statbuf: *Stat) usize {
1112 return syscall2(SYS_stat, @ptrToInt(pathname), @ptrToInt(statbuf));1129 return syscall2(SYS_stat, @ptrToInt(pathname), @ptrToInt(statbuf));
1113}1130}
11141131
1115pub fn lstat(pathname: *const u8, statbuf: *Stat) usize {1132// TODO https://github.com/ziglang/zig/issues/265
1133pub fn lstat(pathname: [*]const u8, statbuf: *Stat) usize {
1116 return syscall2(SYS_lstat, @ptrToInt(pathname), @ptrToInt(statbuf));1134 return syscall2(SYS_lstat, @ptrToInt(pathname), @ptrToInt(statbuf));
1117}1135}
11181136
1119pub fn listxattr(path: *const u8, list: *u8, size: usize) usize {1137// TODO https://github.com/ziglang/zig/issues/265
1138pub fn listxattr(path: [*]const u8, list: [*]u8, size: usize) usize {
1120 return syscall3(SYS_listxattr, @ptrToInt(path), @ptrToInt(list), size);1139 return syscall3(SYS_listxattr, @ptrToInt(path), @ptrToInt(list), size);
1121}1140}
11221141
1123pub fn llistxattr(path: *const u8, list: *u8, size: usize) usize {1142// TODO https://github.com/ziglang/zig/issues/265
1143pub fn llistxattr(path: [*]const u8, list: [*]u8, size: usize) usize {
1124 return syscall3(SYS_llistxattr, @ptrToInt(path), @ptrToInt(list), size);1144 return syscall3(SYS_llistxattr, @ptrToInt(path), @ptrToInt(list), size);
1125}1145}
11261146
1127pub fn flistxattr(fd: usize, list: *u8, size: usize) usize {1147pub fn flistxattr(fd: usize, list: [*]u8, size: usize) usize {
1128 return syscall3(SYS_flistxattr, fd, @ptrToInt(list), size);1148 return syscall3(SYS_flistxattr, fd, @ptrToInt(list), size);
1129}1149}
11301150
1131pub fn getxattr(path: *const u8, name: *const u8, value: *void, size: usize) usize {1151// TODO https://github.com/ziglang/zig/issues/265
1152pub fn getxattr(path: [*]const u8, name: [*]const u8, value: [*]u8, size: usize) usize {
1132 return syscall4(SYS_getxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size);1153 return syscall4(SYS_getxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size);
1133}1154}
11341155
1135pub fn lgetxattr(path: *const u8, name: *const u8, value: *void, size: usize) usize {1156// TODO https://github.com/ziglang/zig/issues/265
1157pub fn lgetxattr(path: [*]const u8, name: [*]const u8, value: [*]u8, size: usize) usize {
1136 return syscall4(SYS_lgetxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size);1158 return syscall4(SYS_lgetxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size);
1137}1159}
11381160
1139pub fn fgetxattr(fd: usize, name: *const u8, value: *void, size: usize) usize {1161// TODO https://github.com/ziglang/zig/issues/265
1162pub fn fgetxattr(fd: usize, name: [*]const u8, value: [*]u8, size: usize) usize {
1140 return syscall4(SYS_lgetxattr, fd, @ptrToInt(name), @ptrToInt(value), size);1163 return syscall4(SYS_lgetxattr, fd, @ptrToInt(name), @ptrToInt(value), size);
1141}1164}
11421165
1143pub fn setxattr(path: *const u8, name: *const u8, value: *const void, size: usize, flags: usize) usize {1166// TODO https://github.com/ziglang/zig/issues/265
1167pub fn setxattr(path: [*]const u8, name: [*]const u8, value: *const void, size: usize, flags: usize) usize {
1144 return syscall5(SYS_setxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size, flags);1168 return syscall5(SYS_setxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size, flags);
1145}1169}
11461170
1147pub fn lsetxattr(path: *const u8, name: *const u8, value: *const void, size: usize, flags: usize) usize {1171// TODO https://github.com/ziglang/zig/issues/265
1172pub fn lsetxattr(path: [*]const u8, name: [*]const u8, value: *const void, size: usize, flags: usize) usize {
1148 return syscall5(SYS_lsetxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size, flags);1173 return syscall5(SYS_lsetxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size, flags);
1149}1174}
11501175
1151pub fn fsetxattr(fd: usize, name: *const u8, value: *const void, size: usize, flags: usize) usize {1176// TODO https://github.com/ziglang/zig/issues/265
1177pub fn fsetxattr(fd: usize, name: [*]const u8, value: *const void, size: usize, flags: usize) usize {
1152 return syscall5(SYS_fsetxattr, fd, @ptrToInt(name), @ptrToInt(value), size, flags);1178 return syscall5(SYS_fsetxattr, fd, @ptrToInt(name), @ptrToInt(value), size, flags);
1153}1179}
11541180
1155pub fn removexattr(path: *const u8, name: *const u8) usize {1181// TODO https://github.com/ziglang/zig/issues/265
1182pub fn removexattr(path: [*]const u8, name: [*]const u8) usize {
1156 return syscall2(SYS_removexattr, @ptrToInt(path), @ptrToInt(name));1183 return syscall2(SYS_removexattr, @ptrToInt(path), @ptrToInt(name));
1157}1184}
11581185
1159pub fn lremovexattr(path: *const u8, name: *const u8) usize {1186// TODO https://github.com/ziglang/zig/issues/265
1187pub fn lremovexattr(path: [*]const u8, name: [*]const u8) usize {
1160 return syscall2(SYS_lremovexattr, @ptrToInt(path), @ptrToInt(name));1188 return syscall2(SYS_lremovexattr, @ptrToInt(path), @ptrToInt(name));
1161}1189}
11621190
1163pub fn fremovexattr(fd: usize, name: *const u8) usize {1191// TODO https://github.com/ziglang/zig/issues/265
1192pub fn fremovexattr(fd: usize, name: [*]const u8) usize {
1164 return syscall2(SYS_fremovexattr, fd, @ptrToInt(name));1193 return syscall2(SYS_fremovexattr, fd, @ptrToInt(name));
1165}1194}
11661195
...@@ -1188,7 +1217,7 @@ pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize {...@@ -1188,7 +1217,7 @@ pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize {
1188 return syscall4(SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev));1217 return syscall4(SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev));
1189}1218}
11901219
1191pub fn epoll_wait(epoll_fd: i32, events: *epoll_event, maxevents: u32, timeout: i32) usize {1220pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
1192 return syscall4(SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout));1221 return syscall4(SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout));
1193}1222}
11941223
std/os/linux/test.zig+2-1
...@@ -35,5 +35,6 @@ test "timer" {...@@ -35,5 +35,6 @@ test "timer" {
35 const events_one: linux.epoll_event = undefined;35 const events_one: linux.epoll_event = undefined;
36 var events = []linux.epoll_event{events_one} ** 8;36 var events = []linux.epoll_event{events_one} ** 8;
3737
38 err = linux.epoll_wait(i32(epoll_fd), &events[0], 8, -1);38 // TODO implicit cast from *[N]T to [*]T
39 err = linux.epoll_wait(i32(epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
39}40}
std/os/linux/vdso.zig+13-13
...@@ -12,7 +12,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -12,7 +12,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
12 var ph_addr: usize = vdso_addr + eh.e_phoff;12 var ph_addr: usize = vdso_addr + eh.e_phoff;
13 const ph = @intToPtr(*elf.Phdr, ph_addr);13 const ph = @intToPtr(*elf.Phdr, ph_addr);
1414
15 var maybe_dynv: ?*usize = null;15 var maybe_dynv: ?[*]usize = null;
16 var base: usize = @maxValue(usize);16 var base: usize = @maxValue(usize);
17 {17 {
18 var i: usize = 0;18 var i: usize = 0;
...@@ -23,7 +23,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -23,7 +23,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
23 const this_ph = @intToPtr(*elf.Phdr, ph_addr);23 const this_ph = @intToPtr(*elf.Phdr, ph_addr);
24 switch (this_ph.p_type) {24 switch (this_ph.p_type) {
25 elf.PT_LOAD => base = vdso_addr + this_ph.p_offset - this_ph.p_vaddr,25 elf.PT_LOAD => base = vdso_addr + this_ph.p_offset - this_ph.p_vaddr,
26 elf.PT_DYNAMIC => maybe_dynv = @intToPtr(*usize, vdso_addr + this_ph.p_offset),26 elf.PT_DYNAMIC => maybe_dynv = @intToPtr([*]usize, vdso_addr + this_ph.p_offset),
27 else => {},27 else => {},
28 }28 }
29 }29 }
...@@ -31,10 +31,10 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -31,10 +31,10 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
31 const dynv = maybe_dynv ?? return 0;31 const dynv = maybe_dynv ?? return 0;
32 if (base == @maxValue(usize)) return 0;32 if (base == @maxValue(usize)) return 0;
3333
34 var maybe_strings: ?*u8 = null;34 var maybe_strings: ?[*]u8 = null;
35 var maybe_syms: ?*elf.Sym = null;35 var maybe_syms: ?[*]elf.Sym = null;
36 var maybe_hashtab: ?*linux.Elf_Symndx = null;36 var maybe_hashtab: ?[*]linux.Elf_Symndx = null;
37 var maybe_versym: ?*u16 = null;37 var maybe_versym: ?[*]u16 = null;
38 var maybe_verdef: ?*elf.Verdef = null;38 var maybe_verdef: ?*elf.Verdef = null;
3939
40 {40 {
...@@ -42,10 +42,10 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -42,10 +42,10 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
42 while (dynv[i] != 0) : (i += 2) {42 while (dynv[i] != 0) : (i += 2) {
43 const p = base + dynv[i + 1];43 const p = base + dynv[i + 1];
44 switch (dynv[i]) {44 switch (dynv[i]) {
45 elf.DT_STRTAB => maybe_strings = @intToPtr(*u8, p),45 elf.DT_STRTAB => maybe_strings = @intToPtr([*]u8, p),
46 elf.DT_SYMTAB => maybe_syms = @intToPtr(*elf.Sym, p),46 elf.DT_SYMTAB => maybe_syms = @intToPtr([*]elf.Sym, p),
47 elf.DT_HASH => maybe_hashtab = @intToPtr(*linux.Elf_Symndx, p),47 elf.DT_HASH => maybe_hashtab = @intToPtr([*]linux.Elf_Symndx, p),
48 elf.DT_VERSYM => maybe_versym = @intToPtr(*u16, p),48 elf.DT_VERSYM => maybe_versym = @intToPtr([*]u16, p),
49 elf.DT_VERDEF => maybe_verdef = @intToPtr(*elf.Verdef, p),49 elf.DT_VERDEF => maybe_verdef = @intToPtr(*elf.Verdef, p),
50 else => {},50 else => {},
51 }51 }
...@@ -65,7 +65,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -65,7 +65,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
65 if (0 == (u32(1) << u5(syms[i].st_info & 0xf) & OK_TYPES)) continue;65 if (0 == (u32(1) << u5(syms[i].st_info & 0xf) & OK_TYPES)) continue;
66 if (0 == (u32(1) << u5(syms[i].st_info >> 4) & OK_BINDS)) continue;66 if (0 == (u32(1) << u5(syms[i].st_info >> 4) & OK_BINDS)) continue;
67 if (0 == syms[i].st_shndx) continue;67 if (0 == syms[i].st_shndx) continue;
68 if (!mem.eql(u8, name, cstr.toSliceConst(&strings[syms[i].st_name]))) continue;68 if (!mem.eql(u8, name, cstr.toSliceConst(strings + syms[i].st_name))) continue;
69 if (maybe_versym) |versym| {69 if (maybe_versym) |versym| {
70 if (!checkver(??maybe_verdef, versym[i], vername, strings))70 if (!checkver(??maybe_verdef, versym[i], vername, strings))
71 continue;71 continue;
...@@ -76,7 +76,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -76,7 +76,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
76 return 0;76 return 0;
77}77}
7878
79fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: *u8) bool {79fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [*]u8) bool {
80 var def = def_arg;80 var def = def_arg;
81 const vsym = @bitCast(u32, vsym_arg) & 0x7fff;81 const vsym = @bitCast(u32, vsym_arg) & 0x7fff;
82 while (true) {82 while (true) {
...@@ -87,5 +87,5 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: *...@@ -87,5 +87,5 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: *
87 def = @intToPtr(*elf.Verdef, @ptrToInt(def) + def.vd_next);87 def = @intToPtr(*elf.Verdef, @ptrToInt(def) + def.vd_next);
88 }88 }
89 const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);89 const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);
90 return mem.eql(u8, vername, cstr.toSliceConst(&strings[aux.vda_name]));90 return mem.eql(u8, vername, cstr.toSliceConst(strings + aux.vda_name));
91}91}
std/os/windows/index.zig+15-15
...@@ -10,7 +10,7 @@ pub extern "advapi32" stdcallcc fn CryptAcquireContextA(...@@ -10,7 +10,7 @@ pub extern "advapi32" stdcallcc fn CryptAcquireContextA(
1010
11pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL;11pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL;
1212
13pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: *BYTE) BOOL;13pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: [*]BYTE) BOOL;
1414
15pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;15pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;
1616
...@@ -61,7 +61,7 @@ pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) BOOL;...@@ -61,7 +61,7 @@ pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) BOOL;
6161
62pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn;62pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn;
6363
64pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: LPCH) BOOL;64pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: [*]u8) BOOL;
6565
66pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;66pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
6767
...@@ -69,7 +69,7 @@ pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out...@@ -69,7 +69,7 @@ pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out
6969
70pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD;70pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD;
7171
72pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?LPCH;72pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8;
7373
74pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;74pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;
7575
...@@ -101,17 +101,17 @@ pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(?*FILETIME) void;...@@ -101,17 +101,17 @@ pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(?*FILETIME) void;
101101
102pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE;102pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE;
103pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL;103pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL;
104pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void;104pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: [*]c_void, dwBytes: SIZE_T) ?[*]c_void;
105pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T;105pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: [*]const c_void) SIZE_T;
106pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) BOOL;106pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: [*]const c_void) BOOL;
107pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T;107pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T;
108pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL;108pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL;
109109
110pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE;110pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE;
111111
112pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void;112pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?[*]c_void;
113113
114pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL;114pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: [*]c_void) BOOL;
115115
116pub extern "kernel32" stdcallcc fn MoveFileExA(116pub extern "kernel32" stdcallcc fn MoveFileExA(
117 lpExistingFileName: LPCSTR,117 lpExistingFileName: LPCSTR,
...@@ -127,7 +127,7 @@ pub extern "kernel32" stdcallcc fn PathFileExists(pszPath: ?LPCTSTR) BOOL;...@@ -127,7 +127,7 @@ pub extern "kernel32" stdcallcc fn PathFileExists(pszPath: ?LPCTSTR) BOOL;
127127
128pub extern "kernel32" stdcallcc fn ReadFile(128pub extern "kernel32" stdcallcc fn ReadFile(
129 in_hFile: HANDLE,129 in_hFile: HANDLE,
130 out_lpBuffer: *c_void,130 out_lpBuffer: [*]c_void,
131 in_nNumberOfBytesToRead: DWORD,131 in_nNumberOfBytesToRead: DWORD,
132 out_lpNumberOfBytesRead: *DWORD,132 out_lpNumberOfBytesRead: *DWORD,
133 in_out_lpOverlapped: ?*OVERLAPPED,133 in_out_lpOverlapped: ?*OVERLAPPED,
...@@ -150,7 +150,7 @@ pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMillis...@@ -150,7 +150,7 @@ pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMillis
150150
151pub extern "kernel32" stdcallcc fn WriteFile(151pub extern "kernel32" stdcallcc fn WriteFile(
152 in_hFile: HANDLE,152 in_hFile: HANDLE,
153 in_lpBuffer: *const c_void,153 in_lpBuffer: [*]const c_void,
154 in_nNumberOfBytesToWrite: DWORD,154 in_nNumberOfBytesToWrite: DWORD,
155 out_lpNumberOfBytesWritten: ?*DWORD,155 out_lpNumberOfBytesWritten: ?*DWORD,
156 in_out_lpOverlapped: ?*OVERLAPPED,156 in_out_lpOverlapped: ?*OVERLAPPED,
...@@ -178,16 +178,16 @@ pub const HMODULE = *@OpaqueType();...@@ -178,16 +178,16 @@ pub const HMODULE = *@OpaqueType();
178pub const INT = c_int;178pub const INT = c_int;
179pub const LPBYTE = *BYTE;179pub const LPBYTE = *BYTE;
180pub const LPCH = *CHAR;180pub const LPCH = *CHAR;
181pub const LPCSTR = *const CHAR;181pub const LPCSTR = [*]const CHAR;
182pub const LPCTSTR = *const TCHAR;182pub const LPCTSTR = [*]const TCHAR;
183pub const LPCVOID = *const c_void;183pub const LPCVOID = *const c_void;
184pub const LPDWORD = *DWORD;184pub const LPDWORD = *DWORD;
185pub const LPSTR = *CHAR;185pub const LPSTR = [*]CHAR;
186pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;186pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;
187pub const LPVOID = *c_void;187pub const LPVOID = *c_void;
188pub const LPWSTR = *WCHAR;188pub const LPWSTR = [*]WCHAR;
189pub const PVOID = *c_void;189pub const PVOID = *c_void;
190pub const PWSTR = *WCHAR;190pub const PWSTR = [*]WCHAR;
191pub const SIZE_T = usize;191pub const SIZE_T = usize;
192pub const TCHAR = if (UNICODE) WCHAR else u8;192pub const TCHAR = if (UNICODE) WCHAR else u8;
193pub const UINT = c_uint;193pub const UINT = c_uint;
std/os/windows/util.zig+1-1
...@@ -42,7 +42,7 @@ pub const WriteError = error{...@@ -42,7 +42,7 @@ pub const WriteError = error{
42};42};
4343
44pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void {44pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void {
45 if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {45 if (windows.WriteFile(handle, @ptrCast([*]const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {
46 const err = windows.GetLastError();46 const err = windows.GetLastError();
47 return switch (err) {47 return switch (err) {
48 windows.ERROR.INVALID_USER_BUFFER => WriteError.SystemResources,48 windows.ERROR.INVALID_USER_BUFFER => WriteError.SystemResources,
std/segmented_list.zig+6-6
...@@ -87,7 +87,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -87,7 +87,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
87 const ShelfIndex = std.math.Log2Int(usize);87 const ShelfIndex = std.math.Log2Int(usize);
8888
89 prealloc_segment: [prealloc_item_count]T,89 prealloc_segment: [prealloc_item_count]T,
90 dynamic_segments: []*T,90 dynamic_segments: [][*]T,
91 allocator: *Allocator,91 allocator: *Allocator,
92 len: usize,92 len: usize,
9393
...@@ -99,7 +99,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -99,7 +99,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
99 .allocator = allocator,99 .allocator = allocator,
100 .len = 0,100 .len = 0,
101 .prealloc_segment = undefined,101 .prealloc_segment = undefined,
102 .dynamic_segments = []*T{},102 .dynamic_segments = [][*]T{},
103 };103 };
104 }104 }
105105
...@@ -160,11 +160,11 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -160,11 +160,11 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
160 const new_cap_shelf_count = shelfCount(new_capacity);160 const new_cap_shelf_count = shelfCount(new_capacity);
161 const old_shelf_count = ShelfIndex(self.dynamic_segments.len);161 const old_shelf_count = ShelfIndex(self.dynamic_segments.len);
162 if (new_cap_shelf_count > old_shelf_count) {162 if (new_cap_shelf_count > old_shelf_count) {
163 self.dynamic_segments = try self.allocator.realloc(*T, self.dynamic_segments, new_cap_shelf_count);163 self.dynamic_segments = try self.allocator.realloc([*]T, self.dynamic_segments, new_cap_shelf_count);
164 var i = old_shelf_count;164 var i = old_shelf_count;
165 errdefer {165 errdefer {
166 self.freeShelves(i, old_shelf_count);166 self.freeShelves(i, old_shelf_count);
167 self.dynamic_segments = self.allocator.shrink(*T, self.dynamic_segments, old_shelf_count);167 self.dynamic_segments = self.allocator.shrink([*]T, self.dynamic_segments, old_shelf_count);
168 }168 }
169 while (i < new_cap_shelf_count) : (i += 1) {169 while (i < new_cap_shelf_count) : (i += 1) {
170 self.dynamic_segments[i] = (try self.allocator.alloc(T, shelfSize(i))).ptr;170 self.dynamic_segments[i] = (try self.allocator.alloc(T, shelfSize(i))).ptr;
...@@ -178,7 +178,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -178,7 +178,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
178 const len = ShelfIndex(self.dynamic_segments.len);178 const len = ShelfIndex(self.dynamic_segments.len);
179 self.freeShelves(len, 0);179 self.freeShelves(len, 0);
180 self.allocator.free(self.dynamic_segments);180 self.allocator.free(self.dynamic_segments);
181 self.dynamic_segments = []*T{};181 self.dynamic_segments = [][*]T{};
182 return;182 return;
183 }183 }
184184
...@@ -190,7 +190,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -190,7 +190,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
190 }190 }
191191
192 self.freeShelves(old_shelf_count, new_cap_shelf_count);192 self.freeShelves(old_shelf_count, new_cap_shelf_count);
193 self.dynamic_segments = self.allocator.shrink(*T, self.dynamic_segments, new_cap_shelf_count);193 self.dynamic_segments = self.allocator.shrink([*]T, self.dynamic_segments, new_cap_shelf_count);
194 }194 }
195195
196 pub fn uncheckedAt(self: *Self, index: usize) *T {196 pub fn uncheckedAt(self: *Self, index: usize) *T {
std/special/bootstrap.zig+12-10
...@@ -5,7 +5,7 @@ const root = @import("@root");...@@ -5,7 +5,7 @@ const root = @import("@root");
5const std = @import("std");5const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8var argc_ptr: *usize = undefined;8var argc_ptr: [*]usize = undefined;
99
10comptime {10comptime {
11 const strong_linkage = builtin.GlobalLinkage.Strong;11 const strong_linkage = builtin.GlobalLinkage.Strong;
...@@ -28,12 +28,12 @@ nakedcc fn _start() noreturn {...@@ -28,12 +28,12 @@ nakedcc fn _start() noreturn {
28 switch (builtin.arch) {28 switch (builtin.arch) {
29 builtin.Arch.x86_64 => {29 builtin.Arch.x86_64 => {
30 argc_ptr = asm ("lea (%%rsp), %[argc]"30 argc_ptr = asm ("lea (%%rsp), %[argc]"
31 : [argc] "=r" (-> *usize)31 : [argc] "=r" (-> [*]usize)
32 );32 );
33 },33 },
34 builtin.Arch.i386 => {34 builtin.Arch.i386 => {
35 argc_ptr = asm ("lea (%%esp), %[argc]"35 argc_ptr = asm ("lea (%%esp), %[argc]"
36 : [argc] "=r" (-> *usize)36 : [argc] "=r" (-> [*]usize)
37 );37 );
38 },38 },
39 else => @compileError("unsupported arch"),39 else => @compileError("unsupported arch"),
...@@ -49,15 +49,17 @@ extern fn WinMainCRTStartup() noreturn {...@@ -49,15 +49,17 @@ extern fn WinMainCRTStartup() noreturn {
49 std.os.windows.ExitProcess(callMain());49 std.os.windows.ExitProcess(callMain());
50}50}
5151
52// TODO https://github.com/ziglang/zig/issues/265
52fn posixCallMainAndExit() noreturn {53fn posixCallMainAndExit() noreturn {
53 const argc = argc_ptr.*;54 const argc = argc_ptr.*;
54 const argv = @ptrCast(**u8, &argc_ptr[1]);55 const argv = @ptrCast([*][*]u8, argc_ptr + 1);
55 const envp_nullable = @ptrCast(*?*u8, &argv[argc + 1]);56
57 const envp_nullable = @ptrCast([*]?[*]u8, argv + argc + 1);
56 var envp_count: usize = 0;58 var envp_count: usize = 0;
57 while (envp_nullable[envp_count]) |_| : (envp_count += 1) {}59 while (envp_nullable[envp_count]) |_| : (envp_count += 1) {}
58 const envp = @ptrCast(**u8, envp_nullable)[0..envp_count];60 const envp = @ptrCast([*][*]u8, envp_nullable)[0..envp_count];
59 if (builtin.os == builtin.Os.linux) {61 if (builtin.os == builtin.Os.linux) {
60 const auxv = &@ptrCast(*usize, envp.ptr)[envp_count + 1];62 const auxv = @ptrCast([*]usize, envp.ptr + envp_count + 1);
61 var i: usize = 0;63 var i: usize = 0;
62 while (auxv[i] != 0) : (i += 2) {64 while (auxv[i] != 0) : (i += 2) {
63 if (auxv[i] < std.os.linux_aux_raw.len) std.os.linux_aux_raw[auxv[i]] = auxv[i + 1];65 if (auxv[i] < std.os.linux_aux_raw.len) std.os.linux_aux_raw[auxv[i]] = auxv[i + 1];
...@@ -68,16 +70,16 @@ fn posixCallMainAndExit() noreturn {...@@ -68,16 +70,16 @@ fn posixCallMainAndExit() noreturn {
68 std.os.posix.exit(callMainWithArgs(argc, argv, envp));70 std.os.posix.exit(callMainWithArgs(argc, argv, envp));
69}71}
7072
71fn callMainWithArgs(argc: usize, argv: **u8, envp: []*u8) u8 {73fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 {
72 std.os.ArgIteratorPosix.raw = argv[0..argc];74 std.os.ArgIteratorPosix.raw = argv[0..argc];
73 std.os.posix_environ_raw = envp;75 std.os.posix_environ_raw = envp;
74 return callMain();76 return callMain();
75}77}
7678
77extern fn main(c_argc: i32, c_argv: **u8, c_envp: *?*u8) i32 {79extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 {
78 var env_count: usize = 0;80 var env_count: usize = 0;
79 while (c_envp[env_count] != null) : (env_count += 1) {}81 while (c_envp[env_count] != null) : (env_count += 1) {}
80 const envp = @ptrCast(**u8, c_envp)[0..env_count];82 const envp = @ptrCast([*][*]u8, c_envp)[0..env_count];
81 return callMainWithArgs(usize(c_argc), c_argv, envp);83 return callMainWithArgs(usize(c_argc), c_argv, envp);
82}84}
8385
std/special/builtin.zig+3-3
...@@ -14,7 +14,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn...@@ -14,7 +14,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
14 }14 }
15}15}
1616
17export fn memset(dest: ?*u8, c: u8, n: usize) ?*u8 {17export fn memset(dest: ?[*]u8, c: u8, n: usize) ?[*]u8 {
18 @setRuntimeSafety(false);18 @setRuntimeSafety(false);
1919
20 var index: usize = 0;20 var index: usize = 0;
...@@ -24,7 +24,7 @@ export fn memset(dest: ?*u8, c: u8, n: usize) ?*u8 {...@@ -24,7 +24,7 @@ export fn memset(dest: ?*u8, c: u8, n: usize) ?*u8 {
24 return dest;24 return dest;
25}25}
2626
27export fn memcpy(noalias dest: ?*u8, noalias src: ?*const u8, n: usize) ?*u8 {27export fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) ?[*]u8 {
28 @setRuntimeSafety(false);28 @setRuntimeSafety(false);
2929
30 var index: usize = 0;30 var index: usize = 0;
...@@ -34,7 +34,7 @@ export fn memcpy(noalias dest: ?*u8, noalias src: ?*const u8, n: usize) ?*u8 {...@@ -34,7 +34,7 @@ export fn memcpy(noalias dest: ?*u8, noalias src: ?*const u8, n: usize) ?*u8 {
34 return dest;34 return dest;
35}35}
3636
37export fn memmove(dest: ?*u8, src: ?*const u8, n: usize) ?*u8 {37export fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) ?[*]u8 {
38 @setRuntimeSafety(false);38 @setRuntimeSafety(false);
3939
40 if (@ptrToInt(dest) < @ptrToInt(src)) {40 if (@ptrToInt(dest) < @ptrToInt(src)) {
test/cases/align.zig+18-31
...@@ -167,54 +167,41 @@ test "@ptrCast preserves alignment of bigger source" {...@@ -167,54 +167,41 @@ test "@ptrCast preserves alignment of bigger source" {
167 assert(@typeOf(ptr) == *align(16) u8);167 assert(@typeOf(ptr) == *align(16) u8);
168}168}
169169
170test "compile-time known array index has best alignment possible" {170test "runtime known array index has best alignment possible" {
171 // take full advantage of over-alignment171 // take full advantage of over-alignment
172 var array align(4) = []u8{172 var array align(4) = []u8{ 1, 2, 3, 4 };
173 1,
174 2,
175 3,
176 4,
177 };
178 assert(@typeOf(&array[0]) == *align(4) u8);173 assert(@typeOf(&array[0]) == *align(4) u8);
179 assert(@typeOf(&array[1]) == *u8);174 assert(@typeOf(&array[1]) == *u8);
180 assert(@typeOf(&array[2]) == *align(2) u8);175 assert(@typeOf(&array[2]) == *align(2) u8);
181 assert(@typeOf(&array[3]) == *u8);176 assert(@typeOf(&array[3]) == *u8);
182177
183 // because align is too small but we still figure out to use 2178 // because align is too small but we still figure out to use 2
184 var bigger align(2) = []u64{179 var bigger align(2) = []u64{ 1, 2, 3, 4 };
185 1,
186 2,
187 3,
188 4,
189 };
190 assert(@typeOf(&bigger[0]) == *align(2) u64);180 assert(@typeOf(&bigger[0]) == *align(2) u64);
191 assert(@typeOf(&bigger[1]) == *align(2) u64);181 assert(@typeOf(&bigger[1]) == *align(2) u64);
192 assert(@typeOf(&bigger[2]) == *align(2) u64);182 assert(@typeOf(&bigger[2]) == *align(2) u64);
193 assert(@typeOf(&bigger[3]) == *align(2) u64);183 assert(@typeOf(&bigger[3]) == *align(2) u64);
194184
195 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2185 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
196 var smaller align(2) = []u32{186 var smaller align(2) = []u32{ 1, 2, 3, 4 };
197 1,187 comptime assert(@typeOf(smaller[0..]) == []align(2) u32);
198 2,188 comptime assert(@typeOf(smaller[0..].ptr) == [*]align(2) u32);
199 3,189 testIndex(smaller[0..].ptr, 0, *align(2) u32);
200 4,190 testIndex(smaller[0..].ptr, 1, *align(2) u32);
201 };191 testIndex(smaller[0..].ptr, 2, *align(2) u32);
202 testIndex(&smaller[0], 0, *align(2) u32);192 testIndex(smaller[0..].ptr, 3, *align(2) u32);
203 testIndex(&smaller[0], 1, *align(2) u32);
204 testIndex(&smaller[0], 2, *align(2) u32);
205 testIndex(&smaller[0], 3, *align(2) u32);
206193
207 // has to use ABI alignment because index known at runtime only194 // has to use ABI alignment because index known at runtime only
208 testIndex2(&array[0], 0, *u8);195 testIndex2(array[0..].ptr, 0, *u8);
209 testIndex2(&array[0], 1, *u8);196 testIndex2(array[0..].ptr, 1, *u8);
210 testIndex2(&array[0], 2, *u8);197 testIndex2(array[0..].ptr, 2, *u8);
211 testIndex2(&array[0], 3, *u8);198 testIndex2(array[0..].ptr, 3, *u8);
212}199}
213fn testIndex(smaller: *align(2) u32, index: usize, comptime T: type) void {200fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void {
214 assert(@typeOf(&smaller[index]) == T);201 comptime assert(@typeOf(&smaller[index]) == T);
215}202}
216fn testIndex2(ptr: *align(4) u8, index: usize, comptime T: type) void {203fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) void {
217 assert(@typeOf(&ptr[index]) == T);204 comptime assert(@typeOf(&ptr[index]) == T);
218}205}
219206
220test "alignstack" {207test "alignstack" {
test/cases/const_slice_child.zig+5-4
...@@ -1,15 +1,16 @@...@@ -1,15 +1,16 @@
1const debug = @import("std").debug;1const debug = @import("std").debug;
2const assert = debug.assert;2const assert = debug.assert;
33
4var argv: *const *const u8 = undefined;4var argv: [*]const [*]const u8 = undefined;
55
6test "const slice child" {6test "const slice child" {
7 const strs = ([]*const u8){7 const strs = ([][*]const u8){
8 c"one",8 c"one",
9 c"two",9 c"two",
10 c"three",10 c"three",
11 };11 };
12 argv = &strs[0];12 // TODO this should implicitly cast
13 argv = @ptrCast([*]const [*]const u8, &strs);
13 bar(strs.len);14 bar(strs.len);
14}15}
1516
...@@ -29,7 +30,7 @@ fn bar(argc: usize) void {...@@ -29,7 +30,7 @@ fn bar(argc: usize) void {
29 foo(args);30 foo(args);
30}31}
3132
32fn strlen(ptr: *const u8) usize {33fn strlen(ptr: [*]const u8) usize {
33 var count: usize = 0;34 var count: usize = 0;
34 while (ptr[count] != 0) : (count += 1) {}35 while (ptr[count] != 0) : (count += 1) {}
35 return count;36 return count;
test/cases/for.zig+2-24
...@@ -35,34 +35,12 @@ fn mangleString(s: []u8) void {...@@ -35,34 +35,12 @@ fn mangleString(s: []u8) void {
35}35}
3636
37test "basic for loop" {37test "basic for loop" {
38 const expected_result = []u8{38 const expected_result = []u8{ 9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 };
39 9,
40 8,
41 7,
42 6,
43 0,
44 1,
45 2,
46 3,
47 9,
48 8,
49 7,
50 6,
51 0,
52 1,
53 2,
54 3,
55 };
5639
57 var buffer: [expected_result.len]u8 = undefined;40 var buffer: [expected_result.len]u8 = undefined;
58 var buf_index: usize = 0;41 var buf_index: usize = 0;
5942
60 const array = []u8{43 const array = []u8{ 9, 8, 7, 6 };
61 9,
62 8,
63 7,
64 6,
65 };
66 for (array) |item| {44 for (array) |item| {
67 buffer[buf_index] = item;45 buffer[buf_index] = item;
68 buf_index += 1;46 buf_index += 1;
test/cases/misc.zig+6-5
...@@ -171,8 +171,8 @@ test "memcpy and memset intrinsics" {...@@ -171,8 +171,8 @@ test "memcpy and memset intrinsics" {
171 var foo: [20]u8 = undefined;171 var foo: [20]u8 = undefined;
172 var bar: [20]u8 = undefined;172 var bar: [20]u8 = undefined;
173173
174 @memset(&foo[0], 'A', foo.len);174 @memset(foo[0..].ptr, 'A', foo.len);
175 @memcpy(&bar[0], &foo[0], bar.len);175 @memcpy(bar[0..].ptr, foo[0..].ptr, bar.len);
176176
177 if (bar[11] != 'A') unreachable;177 if (bar[11] != 'A') unreachable;
178}178}
...@@ -194,7 +194,7 @@ test "slicing" {...@@ -194,7 +194,7 @@ test "slicing" {
194 if (slice.len != 5) unreachable;194 if (slice.len != 5) unreachable;
195195
196 const ptr = &slice[0];196 const ptr = &slice[0];
197 if (ptr[0] != 1234) unreachable;197 if (ptr.* != 1234) unreachable;
198198
199 var slice_rest = array[10..];199 var slice_rest = array[10..];
200 if (slice_rest.len != 10) unreachable;200 if (slice_rest.len != 10) unreachable;
...@@ -464,8 +464,9 @@ test "array 2D const double ptr" {...@@ -464,8 +464,9 @@ test "array 2D const double ptr" {
464}464}
465465
466fn testArray2DConstDoublePtr(ptr: *const f32) void {466fn testArray2DConstDoublePtr(ptr: *const f32) void {
467 assert(ptr[0] == 1.0);467 const ptr2 = @ptrCast([*]const f32, ptr);
468 assert(ptr[1] == 2.0);468 assert(ptr2[0] == 1.0);
469 assert(ptr2[1] == 2.0);
469}470}
470471
471const Tid = builtin.TypeId;472const Tid = builtin.TypeId;
test/cases/pointers.zig+30
...@@ -12,3 +12,33 @@ fn testDerefPtr() void {...@@ -12,3 +12,33 @@ fn testDerefPtr() void {
12 y.* += 1;12 y.* += 1;
13 assert(x == 1235);13 assert(x == 1235);
14}14}
15
16test "pointer arithmetic" {
17 var ptr = c"abcd";
18
19 assert(ptr[0] == 'a');
20 ptr += 1;
21 assert(ptr[0] == 'b');
22 ptr += 1;
23 assert(ptr[0] == 'c');
24 ptr += 1;
25 assert(ptr[0] == 'd');
26 ptr += 1;
27 assert(ptr[0] == 0);
28 ptr -= 1;
29 assert(ptr[0] == 'd');
30 ptr -= 1;
31 assert(ptr[0] == 'c');
32 ptr -= 1;
33 assert(ptr[0] == 'b');
34 ptr -= 1;
35 assert(ptr[0] == 'a');
36}
37
38test "double pointer parsing" {
39 comptime assert(PtrOf(PtrOf(i32)) == **i32);
40}
41
42fn PtrOf(comptime T: type) type {
43 return *T;
44}
test/cases/struct.zig+3-3
...@@ -43,7 +43,7 @@ const VoidStructFieldsFoo = struct {...@@ -43,7 +43,7 @@ const VoidStructFieldsFoo = struct {
4343
44test "structs" {44test "structs" {
45 var foo: StructFoo = undefined;45 var foo: StructFoo = undefined;
46 @memset(@ptrCast(*u8, &foo), 0, @sizeOf(StructFoo));46 @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo));
47 foo.a += 1;47 foo.a += 1;
48 foo.b = foo.a == 1;48 foo.b = foo.a == 1;
49 testFoo(foo);49 testFoo(foo);
...@@ -396,8 +396,8 @@ const Bitfields = packed struct {...@@ -396,8 +396,8 @@ const Bitfields = packed struct {
396test "native bit field understands endianness" {396test "native bit field understands endianness" {
397 var all: u64 = 0x7765443322221111;397 var all: u64 = 0x7765443322221111;
398 var bytes: [8]u8 = undefined;398 var bytes: [8]u8 = undefined;
399 @memcpy(&bytes[0], @ptrCast(*u8, &all), 8);399 @memcpy(bytes[0..].ptr, @ptrCast([*]u8, &all), 8);
400 var bitfields = @ptrCast(*Bitfields, &bytes[0]).*;400 var bitfields = @ptrCast(*Bitfields, bytes[0..].ptr).*;
401401
402 assert(bitfields.f1 == 0x1111);402 assert(bitfields.f1 == 0x1111);
403 assert(bitfields.f2 == 0x2222);403 assert(bitfields.f2 == 0x2222);
test/compare_output.zig+8-8
...@@ -6,7 +6,7 @@ const tests = @import("tests.zig");...@@ -6,7 +6,7 @@ const tests = @import("tests.zig");
6pub fn addCases(cases: *tests.CompareOutputContext) void {6pub fn addCases(cases: *tests.CompareOutputContext) void {
7 cases.addC("hello world with libc",7 cases.addC("hello world with libc",
8 \\const c = @cImport(@cInclude("stdio.h"));8 \\const c = @cImport(@cInclude("stdio.h"));
9 \\export fn main(argc: c_int, argv: **u8) c_int {9 \\export fn main(argc: c_int, argv: [*][*]u8) c_int {
10 \\ _ = c.puts(c"Hello, world!");10 \\ _ = c.puts(c"Hello, world!");
11 \\ return 0;11 \\ return 0;
12 \\}12 \\}
...@@ -139,7 +139,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -139,7 +139,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
139 \\ @cInclude("stdio.h");139 \\ @cInclude("stdio.h");
140 \\});140 \\});
141 \\141 \\
142 \\export fn main(argc: c_int, argv: **u8) c_int {142 \\export fn main(argc: c_int, argv: [*][*]u8) c_int {
143 \\ if (is_windows) {143 \\ if (is_windows) {
144 \\ // we want actual \n, not \r\n144 \\ // we want actual \n, not \r\n
145 \\ _ = c._setmode(1, c._O_BINARY);145 \\ _ = c._setmode(1, c._O_BINARY);
...@@ -284,9 +284,9 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -284,9 +284,9 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
284 cases.addC("expose function pointer to C land",284 cases.addC("expose function pointer to C land",
285 \\const c = @cImport(@cInclude("stdlib.h"));285 \\const c = @cImport(@cInclude("stdlib.h"));
286 \\286 \\
287 \\export fn compare_fn(a: ?*const c_void, b: ?*const c_void) c_int {287 \\export fn compare_fn(a: ?[*]const c_void, b: ?[*]const c_void) c_int {
288 \\ const a_int = @ptrCast(*align(1) const i32, a ?? unreachable);288 \\ const a_int = @ptrCast(*const i32, @alignCast(@alignOf(i32), a));
289 \\ const b_int = @ptrCast(*align(1) const i32, b ?? unreachable);289 \\ const b_int = @ptrCast(*const i32, @alignCast(@alignOf(i32), b));
290 \\ if (a_int.* < b_int.*) {290 \\ if (a_int.* < b_int.*) {
291 \\ return -1;291 \\ return -1;
292 \\ } else if (a_int.* > b_int.*) {292 \\ } else if (a_int.* > b_int.*) {
...@@ -297,9 +297,9 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -297,9 +297,9 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
297 \\}297 \\}
298 \\298 \\
299 \\export fn main() c_int {299 \\export fn main() c_int {
300 \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };300 \\ var array = []u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
301 \\301 \\
302 \\ c.qsort(@ptrCast(*c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);302 \\ c.qsort(@ptrCast(?[*]c_void, array[0..].ptr), c_ulong(array.len), @sizeOf(i32), compare_fn);
303 \\303 \\
304 \\ for (array) |item, i| {304 \\ for (array) |item, i| {
305 \\ if (item != i) {305 \\ if (item != i) {
...@@ -324,7 +324,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -324,7 +324,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
324 \\ @cInclude("stdio.h");324 \\ @cInclude("stdio.h");
325 \\});325 \\});
326 \\326 \\
327 \\export fn main(argc: c_int, argv: **u8) c_int {327 \\export fn main(argc: c_int, argv: [*][*]u8) c_int {
328 \\ if (is_windows) {328 \\ if (is_windows) {
329 \\ // we want actual \n, not \r\n329 \\ // we want actual \n, not \r\n
330 \\ _ = c._setmode(1, c._O_BINARY);330 \\ _ = c._setmode(1, c._O_BINARY);
test/compile_errors.zig+12-3
...@@ -1,6 +1,15 @@...@@ -1,6 +1,15 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "indexing single-item pointer",
6 \\export fn entry(ptr: *i32) i32 {
7 \\ return ptr[1];
8 \\}
9 ,
10 ".tmp_source.zig:2:15: error: indexing not allowed on pointer to single item",
11 );
12
4 cases.add(13 cases.add(
5 "invalid deref on switch target",14 "invalid deref on switch target",
6 \\const NextError = error{NextError};15 \\const NextError = error{NextError};
...@@ -1002,7 +1011,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1002,7 +1011,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1002 \\ return a;1011 \\ return a;
1003 \\}1012 \\}
1004 ,1013 ,
1005 ".tmp_source.zig:3:12: error: expected type 'i32', found '*const u8'",1014 ".tmp_source.zig:3:12: error: expected type 'i32', found '[*]const u8'",
1006 );1015 );
10071016
1008 cases.add(1017 cases.add(
...@@ -2442,13 +2451,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2442,13 +2451,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2442 \\var s_buffer: [10]u8 = undefined;2451 \\var s_buffer: [10]u8 = undefined;
2443 \\pub fn pass(in: []u8) []u8 {2452 \\pub fn pass(in: []u8) []u8 {
2444 \\ var out = &s_buffer;2453 \\ var out = &s_buffer;
2445 \\ out[0].* = in[0];2454 \\ out.*.* = in[0];
2446 \\ return out.*[0..1];2455 \\ return out.*[0..1];
2447 \\}2456 \\}
2448 \\2457 \\
2449 \\export fn entry() usize { return @sizeOf(@typeOf(pass)); }2458 \\export fn entry() usize { return @sizeOf(@typeOf(pass)); }
2450 ,2459 ,
2451 ".tmp_source.zig:4:11: error: attempt to dereference non pointer type '[10]u8'",2460 ".tmp_source.zig:4:10: error: attempt to dereference non pointer type '[10]u8'",
2452 );2461 );
24532462
2454 cases.add(2463 cases.add(
test/translate_c.zig+28-28
...@@ -14,11 +14,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -14,11 +14,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14 \\};14 \\};
15 ,15 ,
16 \\pub const struct_Foo = extern struct {16 \\pub const struct_Foo = extern struct {
17 \\ a: ?*Foo,17 \\ a: ?[*]Foo,
18 \\};18 \\};
19 \\pub const Foo = struct_Foo;19 \\pub const Foo = struct_Foo;
20 \\pub const struct_Bar = extern struct {20 \\pub const struct_Bar = extern struct {
21 \\ a: ?*Foo,21 \\ a: ?[*]Foo,
22 \\};22 \\};
23 );23 );
2424
...@@ -99,7 +99,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -99,7 +99,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
99 cases.add("restrict -> noalias",99 cases.add("restrict -> noalias",
100 \\void foo(void *restrict bar, void *restrict);100 \\void foo(void *restrict bar, void *restrict);
101 ,101 ,
102 \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void;102 \\pub extern fn foo(noalias bar: ?[*]c_void, noalias arg1: ?[*]c_void) void;
103 );103 );
104104
105 cases.add("simple struct",105 cases.add("simple struct",
...@@ -110,7 +110,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -110,7 +110,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
110 ,110 ,
111 \\const struct_Foo = extern struct {111 \\const struct_Foo = extern struct {
112 \\ x: c_int,112 \\ x: c_int,
113 \\ y: ?*u8,113 \\ y: ?[*]u8,
114 \\};114 \\};
115 ,115 ,
116 \\pub const Foo = struct_Foo;116 \\pub const Foo = struct_Foo;
...@@ -141,7 +141,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -141,7 +141,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
141 ,141 ,
142 \\pub const BarB = enum_Bar.B;142 \\pub const BarB = enum_Bar.B;
143 ,143 ,
144 \\pub extern fn func(a: ?*struct_Foo, b: ?*(?*enum_Bar)) void;144 \\pub extern fn func(a: ?[*]struct_Foo, b: ?[*](?[*]enum_Bar)) void;
145 ,145 ,
146 \\pub const Foo = struct_Foo;146 \\pub const Foo = struct_Foo;
147 ,147 ,
...@@ -151,7 +151,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -151,7 +151,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
151 cases.add("constant size array",151 cases.add("constant size array",
152 \\void func(int array[20]);152 \\void func(int array[20]);
153 ,153 ,
154 \\pub extern fn func(array: ?*c_int) void;154 \\pub extern fn func(array: ?[*]c_int) void;
155 );155 );
156156
157 cases.add("self referential struct with function pointer",157 cases.add("self referential struct with function pointer",
...@@ -160,7 +160,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -160,7 +160,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
160 \\};160 \\};
161 ,161 ,
162 \\pub const struct_Foo = extern struct {162 \\pub const struct_Foo = extern struct {
163 \\ derp: ?extern fn(?*struct_Foo) void,163 \\ derp: ?extern fn(?[*]struct_Foo) void,
164 \\};164 \\};
165 ,165 ,
166 \\pub const Foo = struct_Foo;166 \\pub const Foo = struct_Foo;
...@@ -172,7 +172,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -172,7 +172,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
172 ,172 ,
173 \\pub const struct_Foo = @OpaqueType();173 \\pub const struct_Foo = @OpaqueType();
174 ,174 ,
175 \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;175 \\pub extern fn some_func(foo: ?[*]struct_Foo, x: c_int) ?[*]struct_Foo;
176 ,176 ,
177 \\pub const Foo = struct_Foo;177 \\pub const Foo = struct_Foo;
178 );178 );
...@@ -219,11 +219,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -219,11 +219,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
219 \\};219 \\};
220 ,220 ,
221 \\pub const struct_Bar = extern struct {221 \\pub const struct_Bar = extern struct {
222 \\ next: ?*struct_Foo,222 \\ next: ?[*]struct_Foo,
223 \\};223 \\};
224 ,224 ,
225 \\pub const struct_Foo = extern struct {225 \\pub const struct_Foo = extern struct {
226 \\ next: ?*struct_Bar,226 \\ next: ?[*]struct_Bar,
227 \\};227 \\};
228 );228 );
229229
...@@ -233,7 +233,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -233,7 +233,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
233 ,233 ,
234 \\pub const Foo = c_void;234 \\pub const Foo = c_void;
235 ,235 ,
236 \\pub extern fn fun(a: ?*Foo) Foo;236 \\pub extern fn fun(a: ?[*]Foo) Foo;
237 );237 );
238238
239 cases.add("generate inline func for #define global extern fn",239 cases.add("generate inline func for #define global extern fn",
...@@ -505,7 +505,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -505,7 +505,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
505 \\ return 6;505 \\ return 6;
506 \\}506 \\}
507 ,507 ,
508 \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {508 \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?[*]c_void) c_int {
509 \\ if ((a != 0) and (b != 0)) return 0;509 \\ if ((a != 0) and (b != 0)) return 0;
510 \\ if ((b != 0) and (c != null)) return 1;510 \\ if ((b != 0) and (c != null)) return 1;
511 \\ if ((a != 0) and (c != null)) return 2;511 \\ if ((a != 0) and (c != null)) return 2;
...@@ -607,7 +607,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -607,7 +607,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
607 \\pub const struct_Foo = extern struct {607 \\pub const struct_Foo = extern struct {
608 \\ field: c_int,608 \\ field: c_int,
609 \\};609 \\};
610 \\pub export fn read_field(foo: ?*struct_Foo) c_int {610 \\pub export fn read_field(foo: ?[*]struct_Foo) c_int {
611 \\ return (??foo).field;611 \\ return (??foo).field;
612 \\}612 \\}
613 );613 );
...@@ -653,8 +653,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -653,8 +653,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
653 \\ return x;653 \\ return x;
654 \\}654 \\}
655 ,655 ,
656 \\pub export fn foo(x: ?*c_ushort) ?*c_void {656 \\pub export fn foo(x: ?[*]c_ushort) ?[*]c_void {
657 \\ return @ptrCast(?*c_void, x);657 \\ return @ptrCast(?[*]c_void, x);
658 \\}658 \\}
659 );659 );
660660
...@@ -674,7 +674,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -674,7 +674,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
674 \\ return 0;674 \\ return 0;
675 \\}675 \\}
676 ,676 ,
677 \\pub export fn foo() ?*c_int {677 \\pub export fn foo() ?[*]c_int {
678 \\ return null;678 \\ return null;
679 \\}679 \\}
680 );680 );
...@@ -983,7 +983,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -983,7 +983,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
983 \\ *x = 1;983 \\ *x = 1;
984 \\}984 \\}
985 ,985 ,
986 \\pub export fn foo(x: ?*c_int) void {986 \\pub export fn foo(x: ?[*]c_int) void {
987 \\ (??x).* = 1;987 \\ (??x).* = 1;
988 \\}988 \\}
989 );989 );
...@@ -1011,7 +1011,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1011,7 +1011,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1011 ,1011 ,
1012 \\pub fn foo() c_int {1012 \\pub fn foo() c_int {
1013 \\ var x: c_int = 1234;1013 \\ var x: c_int = 1234;
1014 \\ var ptr: ?*c_int = &x;1014 \\ var ptr: ?[*]c_int = &x;
1015 \\ return (??ptr).*;1015 \\ return (??ptr).*;
1016 \\}1016 \\}
1017 );1017 );
...@@ -1021,7 +1021,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1021,7 +1021,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1021 \\ return "bar";1021 \\ return "bar";
1022 \\}1022 \\}
1023 ,1023 ,
1024 \\pub fn foo() ?*const u8 {1024 \\pub fn foo() ?[*]const u8 {
1025 \\ return c"bar";1025 \\ return c"bar";
1026 \\}1026 \\}
1027 );1027 );
...@@ -1150,8 +1150,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1150,8 +1150,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1150 \\ return (float *)a;1150 \\ return (float *)a;
1151 \\}1151 \\}
1152 ,1152 ,
1153 \\fn ptrcast(a: ?*c_int) ?*f32 {1153 \\fn ptrcast(a: ?[*]c_int) ?[*]f32 {
1154 \\ return @ptrCast(?*f32, a);1154 \\ return @ptrCast(?[*]f32, a);
1155 \\}1155 \\}
1156 );1156 );
11571157
...@@ -1173,7 +1173,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1173,7 +1173,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1173 \\ return !c;1173 \\ return !c;
1174 \\}1174 \\}
1175 ,1175 ,
1176 \\pub fn foo(a: c_int, b: f32, c: ?*c_void) c_int {1176 \\pub fn foo(a: c_int, b: f32, c: ?[*]c_void) c_int {
1177 \\ return !(a == 0);1177 \\ return !(a == 0);
1178 \\ return !(a != 0);1178 \\ return !(a != 0);
1179 \\ return !(b != 0);1179 \\ return !(b != 0);
...@@ -1194,7 +1194,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1194,7 +1194,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1194 cases.add("const ptr initializer",1194 cases.add("const ptr initializer",
1195 \\static const char *v0 = "0.0.0";1195 \\static const char *v0 = "0.0.0";
1196 ,1196 ,
1197 \\pub var v0: ?*const u8 = c"0.0.0";1197 \\pub var v0: ?[*]const u8 = c"0.0.0";
1198 );1198 );
11991199
1200 cases.add("static incomplete array inside function",1200 cases.add("static incomplete array inside function",
...@@ -1203,14 +1203,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1203,14 +1203,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1203 \\}1203 \\}
1204 ,1204 ,
1205 \\pub fn foo() void {1205 \\pub fn foo() void {
1206 \\ const v2: *const u8 = c"2.2.2";1206 \\ const v2: [*]const u8 = c"2.2.2";
1207 \\}1207 \\}
1208 );1208 );
12091209
1210 cases.add("macro pointer cast",1210 cases.add("macro pointer cast",
1211 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)1211 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1212 ,1212 ,
1213 \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast(*NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr(*NRF_GPIO_Type, NRF_GPIO_BASE) else (*NRF_GPIO_Type)(NRF_GPIO_BASE);1213 \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*]NRF_GPIO_Type)(NRF_GPIO_BASE);
1214 );1214 );
12151215
1216 cases.add("if on none bool",1216 cases.add("if on none bool",
...@@ -1231,7 +1231,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1231,7 +1231,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1231 \\ B,1231 \\ B,
1232 \\ C,1232 \\ C,
1233 \\};1233 \\};
1234 \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {1234 \\pub fn if_none_bool(a: c_int, b: f32, c: ?[*]c_void, d: enum_SomeEnum) c_int {
1235 \\ if (a != 0) return 0;1235 \\ if (a != 0) return 0;
1236 \\ if (b != 0) return 1;1236 \\ if (b != 0) return 1;
1237 \\ if (c != null) return 2;1237 \\ if (c != null) return 2;
...@@ -1248,7 +1248,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1248,7 +1248,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1248 \\ return 3;1248 \\ return 3;
1249 \\}1249 \\}
1250 ,1250 ,
1251 \\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {1251 \\pub fn while_none_bool(a: c_int, b: f32, c: ?[*]c_void) c_int {
1252 \\ while (a != 0) return 0;1252 \\ while (a != 0) return 0;
1253 \\ while (b != 0) return 1;1253 \\ while (b != 0) return 1;
1254 \\ while (c != null) return 2;1254 \\ while (c != null) return 2;
...@@ -1264,7 +1264,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1264,7 +1264,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1264 \\ return 3;1264 \\ return 3;
1265 \\}1265 \\}
1266 ,1266 ,
1267 \\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {1267 \\pub fn for_none_bool(a: c_int, b: f32, c: ?[*]c_void) c_int {
1268 \\ while (a != 0) return 0;1268 \\ while (a != 0) return 0;
1269 \\ while (b != 0) return 1;1269 \\ while (b != 0) return 1;
1270 \\ while (c != null) return 2;1270 \\ while (c != null) return 2;