From 92f4b4f561f41c68d13dc091cd1ef54ab3a791dc Mon Sep 17 00:00:00 2001 From: Yaossg Date: Tue, 24 Dec 2024 15:00:51 +0800 Subject: [PATCH] 100% coverage --- README.md | 1 + boot.c | 13 +-------- cov-test.sh | 4 +-- run.sh | 2 +- test/error/addressof_rvalue.c | 3 ++ test/error/both_pointers.c | 5 ++++ test/error/branch_mismatch.c | 5 ++++ test/error/deref_non_ptr.c | 4 +++ test/error/deref_void_ptr.c | 4 +++ test/error/endless_arg.c | 3 ++ test/error/endless_char.c | 3 ++ test/error/endless_comment.c | 1 + test/error/endless_enum.c | 1 + test/error/endless_param.c | 1 + test/error/endless_string.c | 3 ++ test/error/invalid_break.c | 3 ++ test/error/invalid_continue.c | 3 ++ test/error/invalid_dots.c | 1 + test/error/invalid_escape.c | 3 ++ test/error/nameless_enum.c | 1 + test/error/negative_array_size.c | 1 + test/error/not_a_function.c | 3 ++ test/error/not_a_name.c | 3 ++ test/error/pointer_binary.c | 4 +++ test/error/pointer_unary.c | 4 +++ test/error/pointers_mismatch.c | 5 ++++ test/error/unexpected_char.c | 1 + test/error/unexpected_expr.c | 3 ++ test/error/unexpected_global.c | 1 + test/error/unexpected_token.c | 3 ++ test/error/variable_array_size.c | 2 ++ test/error/void_arg.c | 1 + test/error/void_global.c | 1 + test/error/void_local.c | 3 ++ test/misc/overflow.c | 24 ++-------------- test/misc/overflow.out | 11 +------- test/operator/assign.c | 28 +++++++++++++++++++ test/operator/assign.out | 12 ++++++++ test/{op => operator}/binary.c | 0 test/{op => operator}/binary.out | 0 test/{op => operator}/inc.c | 0 test/{op => operator}/inc.out | 0 test/{op => operator}/short.c | 0 test/{op => operator}/short.in | 0 test/{op => operator}/short.out | 0 test/unsupported/address_of_pointer.c | 4 +++ test/unsupported/array_of_pointer_arg.c | 1 + test/unsupported/array_of_pointer_global.c | 1 + .../array_of_pointer_local.c} | 2 +- test/unsupported/not_direct_call.c | 3 ++ test/unsupported/too_many_arg.c | 5 ++++ test/unsupported/too_many_param.c | 1 + 52 files changed, 143 insertions(+), 48 deletions(-) create mode 100644 test/error/addressof_rvalue.c create mode 100644 test/error/both_pointers.c create mode 100644 test/error/branch_mismatch.c create mode 100644 test/error/deref_non_ptr.c create mode 100644 test/error/deref_void_ptr.c create mode 100644 test/error/endless_arg.c create mode 100644 test/error/endless_char.c create mode 100644 test/error/endless_comment.c create mode 100644 test/error/endless_enum.c create mode 100644 test/error/endless_param.c create mode 100644 test/error/endless_string.c create mode 100644 test/error/invalid_break.c create mode 100644 test/error/invalid_continue.c create mode 100644 test/error/invalid_dots.c create mode 100644 test/error/invalid_escape.c create mode 100644 test/error/nameless_enum.c create mode 100644 test/error/negative_array_size.c create mode 100644 test/error/not_a_function.c create mode 100644 test/error/not_a_name.c create mode 100644 test/error/pointer_binary.c create mode 100644 test/error/pointer_unary.c create mode 100644 test/error/pointers_mismatch.c create mode 100644 test/error/unexpected_char.c create mode 100644 test/error/unexpected_expr.c create mode 100644 test/error/unexpected_global.c create mode 100644 test/error/unexpected_token.c create mode 100644 test/error/variable_array_size.c create mode 100644 test/error/void_arg.c create mode 100644 test/error/void_global.c create mode 100644 test/error/void_local.c create mode 100644 test/operator/assign.c create mode 100644 test/operator/assign.out rename test/{op => operator}/binary.c (100%) rename test/{op => operator}/binary.out (100%) rename test/{op => operator}/inc.c (100%) rename test/{op => operator}/inc.out (100%) rename test/{op => operator}/short.c (100%) rename test/{op => operator}/short.in (100%) rename test/{op => operator}/short.out (100%) create mode 100644 test/unsupported/address_of_pointer.c create mode 100644 test/unsupported/array_of_pointer_arg.c create mode 100644 test/unsupported/array_of_pointer_global.c rename test/{error/array_pointer.c => unsupported/array_of_pointer_local.c} (53%) create mode 100644 test/unsupported/not_direct_call.c create mode 100644 test/unsupported/too_many_arg.c create mode 100644 test/unsupported/too_many_param.c diff --git a/README.md b/README.md index 78b3f1d..35d031d 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ $ sh boot.sh - 函数只支持最多八个参数。函数声明中支持可变参数,仅用于兼容 C 语言库。 - 类型检查有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。 - 例如函数调用的参数和 `return` 语句不会检查类型。 + - 赋值和比较时没有类型检查,这是为了方便 `0` 成为空指针常量。 ## 限制 diff --git a/boot.c b/boot.c index bd2bdb0..db14a1c 100644 --- a/boot.c +++ b/boot.c @@ -1095,10 +1095,6 @@ int asm_add(int lhs, int rhs) { idx = lhs; } int ptr_type = reg_type[ptr]; - if (ptr_type == TYPE_VOID_PTR) { - fprintf(stderr, "void pointer cannot be arithmetically operated\n"); - exit(1); - } int offset = next_reg(TYPE_INT); _asm_ri("slli", offset, idx, log_step_of(ptr_type)); return asm_rr(ptr_type, "add", ptr, offset); @@ -1120,10 +1116,6 @@ int asm_sub(int lhs, int rhs) { fprintf(stderr, "pointer type mismatch\n"); exit(1); } - if (lhs_type == TYPE_VOID_PTR) { - fprintf(stderr, "void pointer cannot be arithmetically operated\n"); - exit(1); - } int diff = asm_rr(TYPE_INT, "sub", lhs, rhs); _asm_ri("srai", diff, diff, log_step_of(lhs_type)); return diff; @@ -1151,6 +1143,7 @@ int addressof(int reg) { indirection[reg] = 0; } else { printf("cannot take address of this expression"); + exit(1); } return reg; } @@ -1651,10 +1644,6 @@ void parse_local_variable(int type) { unget_token(); expect_token(TOKEN_ASSIGN); int reg = parse_expr(); - if (type != reg_type[reg]) { - fprintf(stderr, "type mismatch in assignment\n"); - exit(1); - } store_into_local(reg, slot); } diff --git a/cov-test.sh b/cov-test.sh index a155324..f37caa7 100644 --- a/cov-test.sh +++ b/cov-test.sh @@ -2,8 +2,8 @@ mkdir -p cov && cd cov && rm * gcc --coverage -g -O0 ../boot.c -o boot.elf for i in ../test/**/*.c; do - echo "Running coverage for test '$(basename $i .c)'" - ./boot.elf < $i > /dev/null + echo "Running coverage for test '$i'" + ./boot.elf < $i > /dev/null 2>/dev/null gcov boot.elf-boot.c done diff --git a/run.sh b/run.sh index 983bab7..268461c 100644 --- a/run.sh +++ b/run.sh @@ -3,4 +3,4 @@ gcc boot.c -o boot.elf && riscv64-linux-gnu-gcc-12 -static $1.s -o $1.elf && qemu-riscv64 $1.elf echo $? -rm $1.s $1.elf boot.elf +rm $1.s $1.elf boot.elf 2> /dev/null diff --git a/test/error/addressof_rvalue.c b/test/error/addressof_rvalue.c new file mode 100644 index 0000000..007fe9b --- /dev/null +++ b/test/error/addressof_rvalue.c @@ -0,0 +1,3 @@ +int main() { + &0; +} \ No newline at end of file diff --git a/test/error/both_pointers.c b/test/error/both_pointers.c new file mode 100644 index 0000000..c6dafd0 --- /dev/null +++ b/test/error/both_pointers.c @@ -0,0 +1,5 @@ +int main() { + int* a; + int* b; + a + b; +} \ No newline at end of file diff --git a/test/error/branch_mismatch.c b/test/error/branch_mismatch.c new file mode 100644 index 0000000..c725043 --- /dev/null +++ b/test/error/branch_mismatch.c @@ -0,0 +1,5 @@ +int main() { + int a; + int* b; + 0 ? a : b; +} \ No newline at end of file diff --git a/test/error/deref_non_ptr.c b/test/error/deref_non_ptr.c new file mode 100644 index 0000000..ef0a4fe --- /dev/null +++ b/test/error/deref_non_ptr.c @@ -0,0 +1,4 @@ +int main() { + int a; + *a; +} \ No newline at end of file diff --git a/test/error/deref_void_ptr.c b/test/error/deref_void_ptr.c new file mode 100644 index 0000000..c6451de --- /dev/null +++ b/test/error/deref_void_ptr.c @@ -0,0 +1,4 @@ +int main() { + void* p; + *p; +} \ No newline at end of file diff --git a/test/error/endless_arg.c b/test/error/endless_arg.c new file mode 100644 index 0000000..1e0b100 --- /dev/null +++ b/test/error/endless_arg.c @@ -0,0 +1,3 @@ +void f() { + f(0 +} \ No newline at end of file diff --git a/test/error/endless_char.c b/test/error/endless_char.c new file mode 100644 index 0000000..436b024 --- /dev/null +++ b/test/error/endless_char.c @@ -0,0 +1,3 @@ +int main() { + ' +} \ No newline at end of file diff --git a/test/error/endless_comment.c b/test/error/endless_comment.c new file mode 100644 index 0000000..22e8364 --- /dev/null +++ b/test/error/endless_comment.c @@ -0,0 +1 @@ +/* \ No newline at end of file diff --git a/test/error/endless_enum.c b/test/error/endless_enum.c new file mode 100644 index 0000000..dfc2d1b --- /dev/null +++ b/test/error/endless_enum.c @@ -0,0 +1 @@ +enum { A = 1 \ No newline at end of file diff --git a/test/error/endless_param.c b/test/error/endless_param.c new file mode 100644 index 0000000..5777bb1 --- /dev/null +++ b/test/error/endless_param.c @@ -0,0 +1 @@ +void f(int a \ No newline at end of file diff --git a/test/error/endless_string.c b/test/error/endless_string.c new file mode 100644 index 0000000..e107bc9 --- /dev/null +++ b/test/error/endless_string.c @@ -0,0 +1,3 @@ +int main() { + " +} \ No newline at end of file diff --git a/test/error/invalid_break.c b/test/error/invalid_break.c new file mode 100644 index 0000000..f2b16d6 --- /dev/null +++ b/test/error/invalid_break.c @@ -0,0 +1,3 @@ +int main() { + break; +} \ No newline at end of file diff --git a/test/error/invalid_continue.c b/test/error/invalid_continue.c new file mode 100644 index 0000000..4f268a6 --- /dev/null +++ b/test/error/invalid_continue.c @@ -0,0 +1,3 @@ +int main() { + continue; +} \ No newline at end of file diff --git a/test/error/invalid_dots.c b/test/error/invalid_dots.c new file mode 100644 index 0000000..945c9b4 --- /dev/null +++ b/test/error/invalid_dots.c @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/test/error/invalid_escape.c b/test/error/invalid_escape.c new file mode 100644 index 0000000..3cafa9d --- /dev/null +++ b/test/error/invalid_escape.c @@ -0,0 +1,3 @@ +int main() { + return '\i'; +} \ No newline at end of file diff --git a/test/error/nameless_enum.c b/test/error/nameless_enum.c new file mode 100644 index 0000000..ce1ab94 --- /dev/null +++ b/test/error/nameless_enum.c @@ -0,0 +1 @@ +enum { 0 }; \ No newline at end of file diff --git a/test/error/negative_array_size.c b/test/error/negative_array_size.c new file mode 100644 index 0000000..75bac71 --- /dev/null +++ b/test/error/negative_array_size.c @@ -0,0 +1 @@ +int a[-1]; \ No newline at end of file diff --git a/test/error/not_a_function.c b/test/error/not_a_function.c new file mode 100644 index 0000000..951df8b --- /dev/null +++ b/test/error/not_a_function.c @@ -0,0 +1,3 @@ +int main() { + f(); +} \ No newline at end of file diff --git a/test/error/not_a_name.c b/test/error/not_a_name.c new file mode 100644 index 0000000..c12c39c --- /dev/null +++ b/test/error/not_a_name.c @@ -0,0 +1,3 @@ +int main() { + a; +} \ No newline at end of file diff --git a/test/error/pointer_binary.c b/test/error/pointer_binary.c new file mode 100644 index 0000000..fe06b1d --- /dev/null +++ b/test/error/pointer_binary.c @@ -0,0 +1,4 @@ +int main() { + int* p; + p * p; +} \ No newline at end of file diff --git a/test/error/pointer_unary.c b/test/error/pointer_unary.c new file mode 100644 index 0000000..be2bad2 --- /dev/null +++ b/test/error/pointer_unary.c @@ -0,0 +1,4 @@ +int main() { + int* p; + ~p; +} \ No newline at end of file diff --git a/test/error/pointers_mismatch.c b/test/error/pointers_mismatch.c new file mode 100644 index 0000000..faea081 --- /dev/null +++ b/test/error/pointers_mismatch.c @@ -0,0 +1,5 @@ +int main() { + int* a; + char* b; + a - b; +} \ No newline at end of file diff --git a/test/error/unexpected_char.c b/test/error/unexpected_char.c new file mode 100644 index 0000000..64845fb --- /dev/null +++ b/test/error/unexpected_char.c @@ -0,0 +1 @@ +` \ No newline at end of file diff --git a/test/error/unexpected_expr.c b/test/error/unexpected_expr.c new file mode 100644 index 0000000..270a786 --- /dev/null +++ b/test/error/unexpected_expr.c @@ -0,0 +1,3 @@ +int main() { + ~~ +} \ No newline at end of file diff --git a/test/error/unexpected_global.c b/test/error/unexpected_global.c new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/test/error/unexpected_global.c @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/test/error/unexpected_token.c b/test/error/unexpected_token.c new file mode 100644 index 0000000..e629775 --- /dev/null +++ b/test/error/unexpected_token.c @@ -0,0 +1,3 @@ +int main() { + if 1 +} \ No newline at end of file diff --git a/test/error/variable_array_size.c b/test/error/variable_array_size.c new file mode 100644 index 0000000..a63cd6b --- /dev/null +++ b/test/error/variable_array_size.c @@ -0,0 +1,2 @@ +int size = 10; +int a[size]; \ No newline at end of file diff --git a/test/error/void_arg.c b/test/error/void_arg.c new file mode 100644 index 0000000..ab2394c --- /dev/null +++ b/test/error/void_arg.c @@ -0,0 +1 @@ +void f(void a) {} \ No newline at end of file diff --git a/test/error/void_global.c b/test/error/void_global.c new file mode 100644 index 0000000..877e6d2 --- /dev/null +++ b/test/error/void_global.c @@ -0,0 +1 @@ +void a; \ No newline at end of file diff --git a/test/error/void_local.c b/test/error/void_local.c new file mode 100644 index 0000000..b439b08 --- /dev/null +++ b/test/error/void_local.c @@ -0,0 +1,3 @@ +void f() { + void a; +} \ No newline at end of file diff --git a/test/misc/overflow.c b/test/misc/overflow.c index 6e4019d..a378c0f 100644 --- a/test/misc/overflow.c +++ b/test/misc/overflow.c @@ -10,32 +10,12 @@ int get_20() { } void dummy(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { - a0 += a1; - printf("%d\n", a0); - a0 -= a1; - printf("%d\n", a0); - a0 *= a1; - printf("%d\n", a0); - a0 /= a1; - printf("%d\n", a0); - a0 %= a1; - printf("%d\n", a0); - a0 &= a1; - printf("%d\n", a0); - a0 |= a1; - printf("%d\n", a0); - a0 ^= a2; - printf("%d\n", a0); - a0 <<= a1; - printf("%d\n", a0); - a0 >>= a1; - printf("%d\n", a0); + printf("%d %d\n", a0); } - int main() { char placeholder[4096]; int a = 1; - dummy((a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(! !0))))))))))))))))))))), 3, a, a, a, a, a, a); + dummy((a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(! !0))))))))))))))))))))), a, a, a, a, a, a, a); return (a=(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(~ ~0)))))))))))))))))))))), (a = +a); } diff --git a/test/misc/overflow.out b/test/misc/overflow.out index 1c9bef7..d38ce7a 100644 --- a/test/misc/overflow.out +++ b/test/misc/overflow.out @@ -1,11 +1,2 @@ -23 -20 -60 -20 -2 -2 -3 -2 -16 -2 +20 1 20 diff --git a/test/operator/assign.c b/test/operator/assign.c new file mode 100644 index 0000000..4932b7b --- /dev/null +++ b/test/operator/assign.c @@ -0,0 +1,28 @@ +int printf(char* format, ...); + +int main() { + int a = 5; + int b = 4; + a += b; + printf("%d\n", a); + a -= b; + printf("%d\n", a); + a *= b; + printf("%d\n", a); + a /= b; + printf("%d\n", a); + a %= b; + printf("%d\n", a); + a &= b; + printf("%d\n", a); + a |= b; + printf("%d\n", a); + a ^= b; + printf("%d\n", a); + a = b; + printf("%d\n", a); + a <<= b; + printf("%d\n", a); + a >>= b; + printf("%d\n", a); +} \ No newline at end of file diff --git a/test/operator/assign.out b/test/operator/assign.out new file mode 100644 index 0000000..27af6d3 --- /dev/null +++ b/test/operator/assign.out @@ -0,0 +1,12 @@ +9 +5 +20 +5 +1 +0 +4 +0 +4 +64 +4 +0 diff --git a/test/op/binary.c b/test/operator/binary.c similarity index 100% rename from test/op/binary.c rename to test/operator/binary.c diff --git a/test/op/binary.out b/test/operator/binary.out similarity index 100% rename from test/op/binary.out rename to test/operator/binary.out diff --git a/test/op/inc.c b/test/operator/inc.c similarity index 100% rename from test/op/inc.c rename to test/operator/inc.c diff --git a/test/op/inc.out b/test/operator/inc.out similarity index 100% rename from test/op/inc.out rename to test/operator/inc.out diff --git a/test/op/short.c b/test/operator/short.c similarity index 100% rename from test/op/short.c rename to test/operator/short.c diff --git a/test/op/short.in b/test/operator/short.in similarity index 100% rename from test/op/short.in rename to test/operator/short.in diff --git a/test/op/short.out b/test/operator/short.out similarity index 100% rename from test/op/short.out rename to test/operator/short.out diff --git a/test/unsupported/address_of_pointer.c b/test/unsupported/address_of_pointer.c new file mode 100644 index 0000000..59fc6ce --- /dev/null +++ b/test/unsupported/address_of_pointer.c @@ -0,0 +1,4 @@ +int main() { + int* p; + &p; +} \ No newline at end of file diff --git a/test/unsupported/array_of_pointer_arg.c b/test/unsupported/array_of_pointer_arg.c new file mode 100644 index 0000000..7513795 --- /dev/null +++ b/test/unsupported/array_of_pointer_arg.c @@ -0,0 +1 @@ +void f(int* a[]) {} \ No newline at end of file diff --git a/test/unsupported/array_of_pointer_global.c b/test/unsupported/array_of_pointer_global.c new file mode 100644 index 0000000..5aeb229 --- /dev/null +++ b/test/unsupported/array_of_pointer_global.c @@ -0,0 +1 @@ +int* a[10]; \ No newline at end of file diff --git a/test/error/array_pointer.c b/test/unsupported/array_of_pointer_local.c similarity index 53% rename from test/error/array_pointer.c rename to test/unsupported/array_of_pointer_local.c index 1e83dbd..cf9adce 100644 --- a/test/error/array_pointer.c +++ b/test/unsupported/array_of_pointer_local.c @@ -1,3 +1,3 @@ -int main() { +void f() { int* a[10]; } \ No newline at end of file diff --git a/test/unsupported/not_direct_call.c b/test/unsupported/not_direct_call.c new file mode 100644 index 0000000..87d1c54 --- /dev/null +++ b/test/unsupported/not_direct_call.c @@ -0,0 +1,3 @@ +int main() { + (main)(); +} \ No newline at end of file diff --git a/test/unsupported/too_many_arg.c b/test/unsupported/too_many_arg.c new file mode 100644 index 0000000..48c5d92 --- /dev/null +++ b/test/unsupported/too_many_arg.c @@ -0,0 +1,5 @@ +void f(); + +int main() { + f(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); +} \ No newline at end of file diff --git a/test/unsupported/too_many_param.c b/test/unsupported/too_many_param.c new file mode 100644 index 0000000..0889855 --- /dev/null +++ b/test/unsupported/too_many_param.c @@ -0,0 +1 @@ +void f(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {} \ No newline at end of file