harec

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

commit e71c40a5ac4f6cde512124b7289c1bfe9e1e0cc1
parent ed0d394707763dd7f00c5921640338eb44ef685f
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri,  1 Jan 2021 14:26:59 -0500

Add expected build failure testing

Diffstat:
Mrt/+linux/syscalls.ha | 25+++++++++++++++++++++++++
Mrt/Makefile | 1+
Art/compile.ha | 36++++++++++++++++++++++++++++++++++++
Mtests/03-pointers.ha | 7++++++-
Mtests/configure | 2+-
5 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -9,13 +9,38 @@ fn syscall6(u64, u64, u64, u64, u64, u64, u64) u64; export fn write(fd: int, buf: *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; + +export fn dup2(old: int, new: int) int = + syscall2(SYS_dup2, old: u64, new: u64): int; + export fn getpid() int = syscall0(SYS_getpid): int; export @noreturn fn exit(status: int) void = syscall1(SYS_exit, status: u64); +export fn fork() int = syscall0(SYS_fork): int; + +export fn execve( + path: *const char, + argv: *[*]nullable *const char, + envp: *[*]nullable *const char, +) int = syscall3(SYS_execve, + path: uintptr: u64, + argv: uintptr: u64, + envp: uintptr: u64): int; + +export fn wait4(pid: int, status: *int, options: int, rusage: *void) void = + syscall4(SYS_wait4, pid: u64, status: uintptr: u64, + options: u64, rusage: uintptr: u64); + +export fn wexitstatus(status: int) int = status & 0xff00 >> 8; + export fn kill(pid: int, signal: int) int = syscall2(SYS_kill, pid: u64, signal: u64): int; +export fn pipe2(pipefd: *[2]int, flags: int) int = + syscall2(SYS_pipe2, pipefd: uintptr: u64, flags: u64): int; + export def SIGHUP: int = 1; export def SIGINT: int = 2; export def SIGQUIT: int = 3; diff --git a/rt/Makefile b/rt/Makefile @@ -1,5 +1,6 @@ libhart_srcs+=\ rt/abort.ha \ + rt/compile.ha \ rt/rtmain.ha libhart.a: harec $(libhart_srcs) $(libhart_objs) diff --git a/rt/compile.ha b/rt/compile.ha @@ -0,0 +1,36 @@ +// Runs the Hare compiler and returns the exit status. +export fn compile(src: str) int = { + let pipefd = [-1, -1]; + pipe2(&pipefd, 0); + + let status: int = 0; + const child = fork(); + if (child == 0) { + close(pipefd[1]); + dup2(pipefd[0], 0); + close(1); + close(2); + + // XXX: This could be simplified a lot with some compiler + // improvements + let path = "./harec"; + let param = "-"; + let argv = [ + path: nullable *const char, + param: nullable *const char, + null: nullable *const char, + ]; + let envp: [1]nullable *const char = [null: nullable *const char]; + execve(path: *const char, + &argv: *[*]nullable *const char, + &envp: *[*]nullable *const char); + abort(); + } else { + close(pipefd[0]); + write(pipefd[1], src: *const char: *void, len(src)); + close(pipefd[1]); + wait4(child, &status, 0, null: *void); + }; + + return status; +}; diff --git a/tests/03-pointers.ha b/tests/03-pointers.ha @@ -1,3 +1,5 @@ +fn rt::compile(src: str) int; + fn basics() void = { let x = 42; let y: *int = &x; @@ -12,7 +14,10 @@ fn _nullable() void = { let y = 42; x = &y; assert(*(x: *int) == 42); - // TODO: Expected failures with nullable pointers + + assert(rt::compile( + "fn test() void = { let x: nullable *int = null; *x; };", + ) != 0); }; export fn main() void = { diff --git a/tests/configure b/tests/configure @@ -10,7 +10,7 @@ tests() { 04-strings do cat <<EOF -tests/$t: rt tests/$t.ha +tests/$t: libhart.a tests/$t.ha @printf 'HAREC %s\t$@\n' "tests/$t" @./harec -o tests/$t.ssa tests/$t.ha @qbe -o tests/$t.s tests/$t.ssa