authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-05 18:03:21-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-05 18:03:21-04:00
log652f4bdf6242462182005f4c7149f13beaaa3259
treee8b131095700c37604ebad9934f836e51538aabe
parent7a0948253636080e5abe59b938761ee7348a7025

disallow unknown-length pointer to opaque

This also means that translate-c has to detect when a pointer to opaque is happening, and use `*` instead of `[*]`. See #1059

14 files changed, 89 insertions(+), 50 deletions(-)

src/analyze.cpp+1
...@@ -384,6 +384,7 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -384,6 +384,7 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
384 bool is_volatile, PtrLen ptr_len, 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));
387 assert(ptr_len == PtrLenSingle || child_type->id != TypeTableEntryIdOpaque);
387388
388 TypeId type_id = {};389 TypeId type_id = {};
389 TypeTableEntry **parent_pointer = nullptr;390 TypeTableEntry **parent_pointer = nullptr;
src/ir.cpp+5-5
...@@ -4620,11 +4620,8 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *...@@ -4620,11 +4620,8 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *
46204620
4621static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {4621static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {
4622 assert(node->type == NodeTypePointerType);4622 assert(node->type == NodeTypePointerType);
4623 // The null check here is for C imports which don't set a token on the AST node. We could potentially4623 PtrLen ptr_len = (node->data.pointer_type.star_token->id == TokenIdStar ||
4624 // update that code to create a fake token and then remove this check.4624 node->data.pointer_type.star_token->id == TokenIdStarStar) ? PtrLenSingle : PtrLenUnknown;
4625 PtrLen ptr_len = (node->data.pointer_type.star_token != nullptr &&
4626 (node->data.pointer_type.star_token->id == TokenIdStar ||
4627 node->data.pointer_type.star_token->id == TokenIdStarStar)) ? PtrLenSingle : PtrLenUnknown;
4628 bool is_const = node->data.pointer_type.is_const;4625 bool is_const = node->data.pointer_type.is_const;
4629 bool is_volatile = node->data.pointer_type.is_volatile;4626 bool is_volatile = node->data.pointer_type.is_volatile;
4630 AstNode *expr_node = node->data.pointer_type.op_expr;4627 AstNode *expr_node = node->data.pointer_type.op_expr;
...@@ -18973,6 +18970,9 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruc...@@ -18973,6 +18970,9 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruc
18973 if (child_type->id == TypeTableEntryIdUnreachable) {18970 if (child_type->id == TypeTableEntryIdUnreachable) {
18974 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));18971 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));
18975 return ira->codegen->builtin_types.entry_invalid;18972 return ira->codegen->builtin_types.entry_invalid;
18973 } else if (child_type->id == TypeTableEntryIdOpaque && instruction->ptr_len == PtrLenUnknown) {
18974 ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque"));
18975 return ira->codegen->builtin_types.entry_invalid;
18976 }18976 }
1897718977
18978 uint32_t align_bytes;18978 uint32_t align_bytes;
src/tokenizer.hpp+2
...@@ -170,6 +170,8 @@ struct Token {...@@ -170,6 +170,8 @@ struct Token {
170 TokenCharLit char_lit;170 TokenCharLit char_lit;
171 } data;171 } data;
172};172};
173// work around conflicting name Token which is also found in libclang
174typedef Token ZigToken;
173175
174struct Tokenization {176struct Tokenization {
175 ZigList<Token> *tokens;177 ZigList<Token> *tokens;
src/translate_c.cpp+33-4
...@@ -276,8 +276,11 @@ static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNod...@@ -276,8 +276,11 @@ static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNod
276 node);276 node);
277}277}
278278
279static AstNode *trans_create_node_ptr_type(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {279static AstNode *trans_create_node_ptr_type(Context *c, bool is_const, bool is_volatile, AstNode *child_node, PtrLen ptr_len) {
280 AstNode *node = trans_create_node(c, NodeTypePointerType);280 AstNode *node = trans_create_node(c, NodeTypePointerType);
281 node->data.pointer_type.star_token = allocate<ZigToken>(1);
282 node->data.pointer_type.star_token->id = (ptr_len == PtrLenSingle) ? TokenIdStar: TokenIdBracketStarBracket;
283 node->data.pointer_type.is_const = is_const;
281 node->data.pointer_type.is_const = is_const;284 node->data.pointer_type.is_const = is_const;
282 node->data.pointer_type.is_volatile = is_volatile;285 node->data.pointer_type.is_volatile = is_volatile;
283 node->data.pointer_type.op_expr = child_node;286 node->data.pointer_type.op_expr = child_node;
...@@ -731,6 +734,30 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {...@@ -731,6 +734,30 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
731 }734 }
732}735}
733736
737static bool type_is_opaque(Context *c, const Type *ty, const SourceLocation &source_loc) {
738 switch (ty->getTypeClass()) {
739 case Type::Builtin: {
740 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
741 return builtin_ty->getKind() == BuiltinType::Void;
742 }
743 case Type::Record: {
744 const RecordType *record_ty = static_cast<const RecordType*>(ty);
745 return record_ty->getDecl()->getDefinition() == nullptr;
746 }
747 case Type::Elaborated: {
748 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
749 return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc);
750 }
751 case Type::Typedef: {
752 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
753 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
754 return type_is_opaque(c, typedef_decl->getUnderlyingType().getTypePtr(), source_loc);
755 }
756 default:
757 return false;
758 }
759}
760
734static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {761static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
735 switch (ty->getTypeClass()) {762 switch (ty->getTypeClass()) {
736 case Type::Builtin:763 case Type::Builtin:
...@@ -855,8 +882,10 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou...@@ -855,8 +882,10 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
855 return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node);882 return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node);
856 }883 }
857884
885 PtrLen ptr_len = type_is_opaque(c, child_qt.getTypePtr(), source_loc) ? PtrLenSingle : PtrLenUnknown;
886
858 AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),887 AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
859 child_qt.isVolatileQualified(), child_node);888 child_qt.isVolatileQualified(), child_node, ptr_len);
860 return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);889 return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);
861 }890 }
862 case Type::Typedef:891 case Type::Typedef:
...@@ -1041,7 +1070,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou...@@ -1041,7 +1070,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
1041 return nullptr;1070 return nullptr;
1042 }1071 }
1043 AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),1072 AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
1044 child_qt.isVolatileQualified(), child_type_node);1073 child_qt.isVolatileQualified(), child_type_node, PtrLenUnknown);
1045 return pointer_node;1074 return pointer_node;
1046 }1075 }
1047 case Type::BlockPointer:1076 case Type::BlockPointer:
...@@ -4448,7 +4477,7 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t...@@ -4448,7 +4477,7 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
4448 } else if (first_tok->id == CTokIdAsterisk) {4477 } else if (first_tok->id == CTokIdAsterisk) {
4449 *tok_i += 1;4478 *tok_i += 1;
44504479
4451 node = trans_create_node_ptr_type(c, false, false, node);4480 node = trans_create_node_ptr_type(c, false, false, node, PtrLenUnknown);
4452 } else {4481 } else {
4453 return node;4482 return node;
4454 }4483 }
std/c/index.zig+10-10
...@@ -20,11 +20,11 @@ pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: *Stat) c_int;...@@ -20,11 +20,11 @@ pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: *Stat) c_int;
20pub 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;
21pub 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;
22pub extern "c" fn raise(sig: c_int) c_int;22pub extern "c" fn raise(sig: c_int) c_int;
23pub 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;
24pub 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;
25pub 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;
26pub 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;
27pub extern "c" fn munmap(addr: [*]c_void, len: usize) c_int;27pub extern "c" fn munmap(addr: *c_void, len: usize) c_int;
28pub extern "c" fn unlink(path: [*]const u8) c_int;28pub extern "c" fn unlink(path: [*]const u8) c_int;
29pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;29pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
30pub 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;
...@@ -48,15 +48,15 @@ pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;...@@ -48,15 +48,15 @@ pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;
48pub 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;
49pub extern "c" fn rmdir(path: [*]const u8) c_int;49pub extern "c" fn rmdir(path: [*]const u8) c_int;
5050
51pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?[*]c_void;51pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;
52pub extern "c" fn malloc(usize) ?[*]c_void;52pub extern "c" fn malloc(usize) ?*c_void;
53pub extern "c" fn realloc([*]c_void, usize) ?[*]c_void;53pub extern "c" fn realloc(*c_void, usize) ?*c_void;
54pub extern "c" fn free([*]c_void) void;54pub extern "c" fn free(*c_void) void;
55pub 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;
5656
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;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;
58pub 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;
59pub 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;
60pub 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;
61pub 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;
6262
std/heap.zig+4-4
...@@ -22,7 +22,7 @@ fn cAlloc(self: *Allocator, n: usize, alignment: u29) ![]u8 {...@@ -22,7 +22,7 @@ fn cAlloc(self: *Allocator, n: usize, alignment: u29) ![]u8 {
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
...@@ -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([*]c_void, 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;
...@@ -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([*]c_void, 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/darwin.zig+4-4
...@@ -327,7 +327,7 @@ pub fn raise(sig: i32) usize {...@@ -327,7 +327,7 @@ pub fn raise(sig: i32) usize {
327}327}
328328
329pub fn read(fd: i32, buf: [*]u8, nbyte: usize) usize {329pub fn read(fd: i32, buf: [*]u8, nbyte: usize) usize {
330 return errnoWrap(c.read(fd, @ptrCast([*]c_void, buf), nbyte));330 return errnoWrap(c.read(fd, @ptrCast(*c_void, buf), nbyte));
331}331}
332332
333pub fn stat(noalias path: [*]const u8, noalias buf: *stat) usize {333pub fn stat(noalias path: [*]const u8, noalias buf: *stat) usize {
...@@ -335,17 +335,17 @@ pub fn stat(noalias path: [*]const u8, noalias buf: *stat) usize {...@@ -335,17 +335,17 @@ pub fn stat(noalias path: [*]const u8, noalias buf: *stat) usize {
335}335}
336336
337pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) usize {337pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) usize {
338 return errnoWrap(c.write(fd, @ptrCast([*]const c_void, buf), nbyte));338 return errnoWrap(c.write(fd, @ptrCast(*const c_void, buf), nbyte));
339}339}
340340
341pub 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 {
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 ptr_result = c.mmap(@ptrCast(*c_void, address), length, @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
343 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));343 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));
344 return errnoWrap(isize_result);344 return errnoWrap(isize_result);
345}345}
346346
347pub fn munmap(address: usize, length: usize) usize {347pub fn munmap(address: usize, length: usize) usize {
348 return errnoWrap(c.munmap(@intToPtr([*]c_void, address), length));348 return errnoWrap(c.munmap(@intToPtr(*c_void, address), length));
349}349}
350350
351pub fn unlink(path: [*]const u8) usize {351pub fn unlink(path: [*]const u8) usize {
std/os/file.zig+1-1
...@@ -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.ptr + 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+2-2
...@@ -2362,7 +2362,7 @@ pub const Thread = struct {...@@ -2362,7 +2362,7 @@ pub const Thread = struct {
2362 },2362 },
2363 builtin.Os.windows => struct {2363 builtin.Os.windows => struct {
2364 handle: windows.HANDLE,2364 handle: windows.HANDLE,
2365 alloc_start: [*]c_void,2365 alloc_start: *c_void,
2366 heap_handle: windows.HANDLE,2366 heap_handle: windows.HANDLE,
2367 },2367 },
2368 else => @compileError("Unsupported OS"),2368 else => @compileError("Unsupported OS"),
...@@ -2533,7 +2533,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread...@@ -2533,7 +2533,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
25332533
2534 // align to page2534 // align to page
2535 stack_end -= stack_end % os.page_size;2535 stack_end -= stack_end % os.page_size;
2536 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);
25372537
2538 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));
2539 switch (err) {2539 switch (err) {
std/os/windows/index.zig+7-7
...@@ -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,
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,
test/compare_output.zig+2-2
...@@ -284,7 +284,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -284,7 +284,7 @@ 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(*const i32, @alignCast(@alignOf(i32), a));288 \\ const a_int = @ptrCast(*const i32, @alignCast(@alignOf(i32), a));
289 \\ const b_int = @ptrCast(*const i32, @alignCast(@alignOf(i32), b));289 \\ const b_int = @ptrCast(*const i32, @alignCast(@alignOf(i32), b));
290 \\ if (a_int.* < b_int.*) {290 \\ if (a_int.* < b_int.*) {
...@@ -299,7 +299,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -299,7 +299,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
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..].ptr), 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) {
test/compile_errors.zig+7
...@@ -1,6 +1,13 @@...@@ -1,6 +1,13 @@
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 "unknown length pointer to opaque",
6 \\export const T = [*]@OpaqueType();
7 ,
8 ".tmp_source.zig:1:18: error: unknown-length pointer to opaque",
9 );
10
4 cases.add(11 cases.add(
5 "error when evaluating return type",12 "error when evaluating return type",
6 \\const Foo = struct {13 \\const Foo = struct {
test/translate_c.zig+10-10
...@@ -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",
...@@ -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 );
...@@ -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;
...@@ -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
...@@ -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);
...@@ -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;