Commit 8e3ab28be9
Changed files (4)
src/analyze.cpp
@@ -4168,6 +4168,16 @@ static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *
return wanted_type;
}
+static bool type_is_codegen_pointer(TypeTableEntry *type) {
+ if (type->id == TypeTableEntryIdPointer) return true;
+ if (type->id == TypeTableEntryIdFn) return true;
+ if (type->id == TypeTableEntryIdMaybe) {
+ if (type->data.maybe.child_type->id == TypeTableEntryIdPointer) return true;
+ if (type->data.maybe.child_type->id == TypeTableEntryIdFn) return true;
+ }
+ return false;
+}
+
static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
AstNode *node)
{
@@ -4207,7 +4217,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
// explicit cast from pointer to isize or usize
if ((wanted_type_canon == g->builtin_types.entry_isize || wanted_type_canon == g->builtin_types.entry_usize) &&
- actual_type_canon->id == TypeTableEntryIdPointer)
+ type_is_codegen_pointer(actual_type_canon))
{
return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPtrToInt, false);
}
@@ -6193,9 +6203,8 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
AstNodeParamDecl *param_decl = ¶m_decl_node->data.param_decl;
TypeTableEntry *type = unwrapped_node_type(param_decl->type);
- if (param_decl->is_noalias && type->id != TypeTableEntryIdPointer) {
- add_node_error(g, param_decl_node,
- buf_sprintf("noalias on non-pointer parameter"));
+ if (param_decl->is_noalias && !type_is_codegen_pointer(type)) {
+ add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter"));
}
if (fn_type->data.fn.fn_type_id.is_extern && type->id == TypeTableEntryIdStruct) {
src/codegen.cpp
@@ -3923,7 +3923,7 @@ static void do_code_gen(CodeGen *g) {
TypeTableEntry *param_type = info->type;
LLVMValueRef argument_val = LLVMGetParam(fn_table_entry->fn_value, gen_index);
bool param_is_noalias = param_node->data.param_decl.is_noalias;
- if (param_type->id == TypeTableEntryIdPointer && param_is_noalias) {
+ if (param_is_noalias) {
LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);
}
if ((param_type->id == TypeTableEntryIdPointer && (param_type->data.pointer.is_const || fn_table_entry->is_pure)) ||
std/linux.zig
@@ -402,7 +402,7 @@ pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: i32) -> isize {
}
pub fn recvfrom(fd: i32, noalias buf: &u8, len: isize, flags: i32,
- noalias addr: &sockaddr, noalias alen: &socklen_t) -> isize
+ noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) -> isize
{
arch.syscall6(arch.SYS_recvfrom, fd, isize(buf), len, flags, isize(addr), isize(alen))
}
@@ -419,7 +419,7 @@ pub fn listen(fd: i32, backlog: i32) -> isize {
arch.syscall2(arch.SYS_listen, fd, backlog)
}
-pub fn sendto(fd: i32, buf: &const u8, len: isize, flags: i32, addr: &const sockaddr, alen: socklen_t) -> isize {
+pub fn sendto(fd: i32, buf: &const u8, len: isize, flags: i32, addr: ?&const sockaddr, alen: socklen_t) -> isize {
arch.syscall6(arch.SYS_sendto, fd, isize(buf), len, flags, isize(addr), isize(alen))
}
std/net.zig
@@ -6,10 +6,42 @@ pub error SigInterrupt;
pub error Unexpected;
pub error Io;
pub error TimedOut;
+pub error ConnectionReset;
+pub error NoMem;
+pub error NotSocket;
struct Connection {
socket_fd: i32,
+ pub fn send(c: Connection, buf: []const u8) -> %isize {
+ const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);
+ const send_err = linux.get_errno(send_ret);
+ switch (send_err) {
+ 0 => return send_ret,
+ errno.EINVAL => unreachable{},
+ errno.EFAULT => unreachable{},
+ errno.ECONNRESET => return error.ConnectionReset,
+ errno.EINTR => return error.SigInterrupt,
+ // TODO there are more possible errors
+ else => return error.Unexpected,
+ }
+ }
+
+ pub fn recv(c: Connection, buf: []u8) -> %isize {
+ const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);
+ const recv_err = linux.get_errno(recv_ret);
+ switch (recv_err) {
+ 0 => return recv_ret,
+ errno.EINVAL => unreachable{},
+ errno.EFAULT => unreachable{},
+ errno.ENOTSOCK => return error.NotSocket,
+ errno.EINTR => return error.SigInterrupt,
+ errno.ENOMEM => return error.NoMem,
+ // TODO more error values
+ else => return error.Unexpected,
+ }
+ }
+
pub fn close(c: Connection) -> %void {
switch (linux.get_errno(linux.close(c.socket_fd))) {
0 => return,