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:
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