100% coverage
This commit is contained in:
parent
49ed7c5df5
commit
92f4b4f561
@ -138,6 +138,7 @@ $ sh boot.sh
|
||||
- 函数只支持最多八个参数。函数声明中支持可变参数,仅用于兼容 C 语言库。
|
||||
- 类型检查有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。
|
||||
- 例如函数调用的参数和 `return` 语句不会检查类型。
|
||||
- 赋值和比较时没有类型检查,这是为了方便 `0` 成为空指针常量。
|
||||
|
||||
|
||||
## 限制
|
||||
|
13
boot.c
13
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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
2
run.sh
2
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
|
||||
|
3
test/error/addressof_rvalue.c
Normal file
3
test/error/addressof_rvalue.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
&0;
|
||||
}
|
5
test/error/both_pointers.c
Normal file
5
test/error/both_pointers.c
Normal file
@ -0,0 +1,5 @@
|
||||
int main() {
|
||||
int* a;
|
||||
int* b;
|
||||
a + b;
|
||||
}
|
5
test/error/branch_mismatch.c
Normal file
5
test/error/branch_mismatch.c
Normal file
@ -0,0 +1,5 @@
|
||||
int main() {
|
||||
int a;
|
||||
int* b;
|
||||
0 ? a : b;
|
||||
}
|
4
test/error/deref_non_ptr.c
Normal file
4
test/error/deref_non_ptr.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main() {
|
||||
int a;
|
||||
*a;
|
||||
}
|
4
test/error/deref_void_ptr.c
Normal file
4
test/error/deref_void_ptr.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main() {
|
||||
void* p;
|
||||
*p;
|
||||
}
|
3
test/error/endless_arg.c
Normal file
3
test/error/endless_arg.c
Normal file
@ -0,0 +1,3 @@
|
||||
void f() {
|
||||
f(0
|
||||
}
|
3
test/error/endless_char.c
Normal file
3
test/error/endless_char.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
'
|
||||
}
|
1
test/error/endless_comment.c
Normal file
1
test/error/endless_comment.c
Normal file
@ -0,0 +1 @@
|
||||
/*
|
1
test/error/endless_enum.c
Normal file
1
test/error/endless_enum.c
Normal file
@ -0,0 +1 @@
|
||||
enum { A = 1
|
1
test/error/endless_param.c
Normal file
1
test/error/endless_param.c
Normal file
@ -0,0 +1 @@
|
||||
void f(int a
|
3
test/error/endless_string.c
Normal file
3
test/error/endless_string.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
"
|
||||
}
|
3
test/error/invalid_break.c
Normal file
3
test/error/invalid_break.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
break;
|
||||
}
|
3
test/error/invalid_continue.c
Normal file
3
test/error/invalid_continue.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
continue;
|
||||
}
|
1
test/error/invalid_dots.c
Normal file
1
test/error/invalid_dots.c
Normal file
@ -0,0 +1 @@
|
||||
.
|
3
test/error/invalid_escape.c
Normal file
3
test/error/invalid_escape.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
return '\i';
|
||||
}
|
1
test/error/nameless_enum.c
Normal file
1
test/error/nameless_enum.c
Normal file
@ -0,0 +1 @@
|
||||
enum { 0 };
|
1
test/error/negative_array_size.c
Normal file
1
test/error/negative_array_size.c
Normal file
@ -0,0 +1 @@
|
||||
int a[-1];
|
3
test/error/not_a_function.c
Normal file
3
test/error/not_a_function.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
f();
|
||||
}
|
3
test/error/not_a_name.c
Normal file
3
test/error/not_a_name.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
a;
|
||||
}
|
4
test/error/pointer_binary.c
Normal file
4
test/error/pointer_binary.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main() {
|
||||
int* p;
|
||||
p * p;
|
||||
}
|
4
test/error/pointer_unary.c
Normal file
4
test/error/pointer_unary.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main() {
|
||||
int* p;
|
||||
~p;
|
||||
}
|
5
test/error/pointers_mismatch.c
Normal file
5
test/error/pointers_mismatch.c
Normal file
@ -0,0 +1,5 @@
|
||||
int main() {
|
||||
int* a;
|
||||
char* b;
|
||||
a - b;
|
||||
}
|
1
test/error/unexpected_char.c
Normal file
1
test/error/unexpected_char.c
Normal file
@ -0,0 +1 @@
|
||||
`
|
3
test/error/unexpected_expr.c
Normal file
3
test/error/unexpected_expr.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
~~
|
||||
}
|
1
test/error/unexpected_global.c
Normal file
1
test/error/unexpected_global.c
Normal file
@ -0,0 +1 @@
|
||||
0
|
3
test/error/unexpected_token.c
Normal file
3
test/error/unexpected_token.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
if 1
|
||||
}
|
2
test/error/variable_array_size.c
Normal file
2
test/error/variable_array_size.c
Normal file
@ -0,0 +1,2 @@
|
||||
int size = 10;
|
||||
int a[size];
|
1
test/error/void_arg.c
Normal file
1
test/error/void_arg.c
Normal file
@ -0,0 +1 @@
|
||||
void f(void a) {}
|
1
test/error/void_global.c
Normal file
1
test/error/void_global.c
Normal file
@ -0,0 +1 @@
|
||||
void a;
|
3
test/error/void_local.c
Normal file
3
test/error/void_local.c
Normal file
@ -0,0 +1,3 @@
|
||||
void f() {
|
||||
void a;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -1,11 +1,2 @@
|
||||
23
|
||||
20
|
||||
60
|
||||
20
|
||||
2
|
||||
2
|
||||
3
|
||||
2
|
||||
16
|
||||
2
|
||||
20 1
|
||||
20
|
||||
|
28
test/operator/assign.c
Normal file
28
test/operator/assign.c
Normal file
@ -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);
|
||||
}
|
12
test/operator/assign.out
Normal file
12
test/operator/assign.out
Normal file
@ -0,0 +1,12 @@
|
||||
9
|
||||
5
|
||||
20
|
||||
5
|
||||
1
|
||||
0
|
||||
4
|
||||
0
|
||||
4
|
||||
64
|
||||
4
|
||||
0
|
4
test/unsupported/address_of_pointer.c
Normal file
4
test/unsupported/address_of_pointer.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main() {
|
||||
int* p;
|
||||
&p;
|
||||
}
|
1
test/unsupported/array_of_pointer_arg.c
Normal file
1
test/unsupported/array_of_pointer_arg.c
Normal file
@ -0,0 +1 @@
|
||||
void f(int* a[]) {}
|
1
test/unsupported/array_of_pointer_global.c
Normal file
1
test/unsupported/array_of_pointer_global.c
Normal file
@ -0,0 +1 @@
|
||||
int* a[10];
|
@ -1,3 +1,3 @@
|
||||
int main() {
|
||||
void f() {
|
||||
int* a[10];
|
||||
}
|
3
test/unsupported/not_direct_call.c
Normal file
3
test/unsupported/not_direct_call.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
(main)();
|
||||
}
|
5
test/unsupported/too_many_arg.c
Normal file
5
test/unsupported/too_many_arg.c
Normal file
@ -0,0 +1,5 @@
|
||||
void f();
|
||||
|
||||
int main() {
|
||||
f(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
}
|
1
test/unsupported/too_many_param.c
Normal file
1
test/unsupported/too_many_param.c
Normal file
@ -0,0 +1 @@
|
||||
void f(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {}
|
Loading…
Reference in New Issue
Block a user