harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 46f819db532a864b1934a81c66a75376eaacdb41
parent e3dbd78a2a5dc4f1d004a2462efa8e98c622b596
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun,  3 Jan 2021 12:30:19 -0500

Prevent assignment of *const <type> to *void

Diffstat:
Minclude/types.h | 1+
Mrt/+linux/syscalls.ha | 2+-
Mrt/abort.ha | 4----
Msrc/type_store.c | 8+++++---
Msrc/types.c | 6++++++
5 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/include/types.h b/include/types.h @@ -151,6 +151,7 @@ extern const struct type builtin_type_const_uintptr, builtin_type_const_rune, builtin_type_const_size, + builtin_type_const_void, // etc builtin_type_const_ptr_char, builtin_type_str, diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -6,7 +6,7 @@ fn syscall4(u64, u64, u64, u64, u64) u64; fn syscall5(u64, u64, u64, u64, u64, u64) u64; fn syscall6(u64, u64, u64, u64, u64, u64, u64) u64; -export fn write(fd: int, buf: *void, count: size) size = +export fn write(fd: int, buf: *const void, count: size) size = syscall3(SYS_write, fd: u64, buf: uintptr: u64, count: u64): size; export fn close(fd: int) int = syscall1(SYS_close, fd: u64): int; diff --git a/rt/abort.ha b/rt/abort.ha @@ -1,8 +1,4 @@ export @noreturn @symbol("rt.abort") fn _abort(msg: str) void = { - // XXX: these implicit casts call const to fall off because const types - // are assignable from non-const types. This should not transit pointer - // secondaries. Write should be updated to *const void, but not before - // the compiler catches the error. const prefix = "Abort: "; write(2, prefix: *const char, len(prefix)); write(2, msg: *const char, len(msg)); diff --git a/src/type_store.c b/src/type_store.c @@ -77,8 +77,10 @@ type_is_assignable(struct type_store *store, case TYPE_STORAGE_NULL: return to->pointer.flags & PTR_NULLABLE; case TYPE_STORAGE_POINTER: - if (to->pointer.referent->storage != TYPE_STORAGE_VOID && - to->pointer.referent != from->pointer.referent) { + if (to->pointer.referent->storage == TYPE_STORAGE_VOID) { + // TODO: const transitivity + return to->pointer.referent->flags == from->pointer.referent->flags; + } else if (to->pointer.referent != from->pointer.referent) { return false; } if (from->pointer.flags & PTR_NULLABLE) { @@ -223,7 +225,7 @@ builtin_type_for_storage(enum type_storage storage, bool is_const) case TYPE_STORAGE_UINTPTR: return is_const ? &builtin_type_const_uintptr : &builtin_type_uintptr; case TYPE_STORAGE_VOID: - return &builtin_type_void; // const void and void are the same type + return is_const ? &builtin_type_const_void : &builtin_type_void; case TYPE_STORAGE_NULL: return &builtin_type_null; // const null and null are the same type case TYPE_STORAGE_STRING: diff --git a/src/types.c b/src/types.c @@ -398,6 +398,12 @@ builtin_type_const_size = { .flags = TYPE_CONST, .size = 8, // XXX: ARCH .align = 8, +}, +builtin_type_const_void = { + .storage = TYPE_STORAGE_VOID, + .flags = TYPE_CONST, + .size = 0, + .align = 0, }; // Others