-
Notifications
You must be signed in to change notification settings - Fork 0
c compiler chains logs
hiromi-mi edited this page Mar 5, 2023
·
1 revision
- コンパイルは通るがテストが一部成功しない
- ソースコード変更なしでOK
hiromimi@tachyon:~/dev/compile/9cc$ ls -1 *.c | xargs -L 1 ../8cc/8cc -c
hiromimi@tachyon:~/dev/compile/9cc$ make
cc -o 9cc gen_ir.o gen_x86.o irdump.o liveness.o main.o opt.o parse.o preprocess.o regalloc.o sema.o token.o util.o util_test.o
test/test.c のコンパイルが通らない
hiromimi@tachyon:~/dev/compile/9cc$ make test
./9cc -test
error at test/test.c:7:269
#define EXPECT(expected, expr) do { int e1 = (expected); int e2 = (expr); if (e1 == e2) { fprintf(stderr, "%s => %d\n", #expr, e2); } else { fprintf(stderr, "line %d: %s: %d expected, but got %d\n", __LINE__, #expr, e1, e2); exit(1); } } while (0)
^
primary expression expected
make: *** [Makefile:12: test] エラー 1
- Hello, World を手元で作ったら (PIE周りのエラーを除き) 普通にビルドできたので、100%壊れているわけではない
- 9cc -> 8cc が通らないのに 8cc -> 9cc は通るのはおもしろい
コンパイル不可
hiromimi@tachyon:~/dev/compile/sk2cc$ ../9cc/9cc_orig as_gen.c
error at sk2cc.h:45:14
#define EOF (-1)
^
parameter name expected
関数形式マクロだと誤解していそう
ビルド+セルフホストOK。diffは以下の通り。
diff --git a/Makefile b/Makefile
index d2be0c9..146e957 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ build/g0/%.o : src/%.c src/hoc.h
$(CC) $(CFLAGS) -c $< -o $@
build/g1/%.s: src/%.c hoc
- ./hoc $< > $@
+ ./hoc_chibicc $< > $@
build_g1: $(G1_ASMS)
$(CC) -g -static -o build/g1/hoc $(G1_ASMS) $(CFLAGS) $(LDFLAGS)
@@ -26,7 +26,7 @@ build_g2: $(G2_ASMS)
test: hoc build_g1 build_g2 FORCE
./test.sh
- ./hoc test/pp_test.c > test/pp_test.s
+ ./hoc_chibicc test/pp_test.c > test/pp_test.s
$(CC) -g -static -o test/pp_test.out test/pp_test.s
./test/pp_test.out
diff --git a/test.sh b/test.sh
index 4655adb..91dad34 100755
--- a/test.sh
+++ b/test.sh
@@ -5,7 +5,7 @@ echo "~~~ gcc ~~~" &&
./test/tmp.out &&
gcc -I./include -D__hoc__ -E -P test/test.c > test/tmp.c &&
echo "~~~ generation 0 ~~~" &&
- ./hoc test/tmp.c > test/tmp.s &&
+ ./hoc_chibicc test/tmp.c > test/tmp.s &&
gcc -static -o test/tmp.out test/tmp.s &&
./test/tmp.out &&
echo "~~~ generation 1 ~~~" &&
まず、以下を実行してビルド可能にする
$ for x in *.c; do gcc -E -D__hoc__ $x > ../src2/$x; done$ sed -e "s/^# [0-9].*$//g" -i *.c
hiromimi@tachyon:~/dev/compile/hoc_nyan/src2$ ls -1 *.c | xargs -L 1 ../../8cc/8cc_gcc -S
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: emit.c:468:11: assume returning int: va_start()
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: emit.c:480:11: assume returning int: va_start()
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: gen_x86.c:470:11: assume returning int: va_start()
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: parse.c:1273:2: type specifier missing, assuming int
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: parse.c:1282:2: type specifier missing, assuming int
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: utils.c:450:11: assume returning int: va_start()
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: utils.c:463:11: assume returning int: va_start()
[WARN] /home/hiromimi/dev/compile/8cc/8cc.h:427: utils.c:477:11: assume returning int: va_start()
$ ls -1 *.c | xargs -L 1 ../../9cc/9cc
動作しない
; expected
error at token.c:9:14
typedef long size_t;
^
; expected
error at utils.c:9:14
typedef long size_t;
$ ls -1 *.c | xargs -L 1 ../../sk2cc/sk2cc
sema.c:454:41: error: invalid operand types. (at sema.c:866)
for (GVar* gvar = prog->globals; gvar != 0; gvar = gvar->next) {
^
token.c:463:36: error: invalid operand types. (at sema.c:807)
size_t len = strchr(start, '\n') - start;
^
utils.c:466:7: error: number of parameters should be 0, but got 1. (at sema.c:565)
exit(1);
- hsjoihs さんによるコメント:
- 最初のは 「0 というリテラルは、ポインタの文脈の場合 null pointer となる」というのを検知していない部分がある
- 次のはポインタ引くポインタ
C言語に標準規格があるのがいかに有用かがわかります 😇
hiromimi@tachyon:~/dev/compile/8cc$ make
../chibicc/chibicc_orig -c -o main.o main.c
../chibicc/chibicc_orig -c -o cpp.o cpp.c
make: *** [<ビルトイン>: cpp.o] エラー 1
cpp.o が生成できていないので、試してみると
hiromimi@tachyon:~/dev/compile/8cc$ ../chibicc/chibicc_orig -c -o cpp.o cpp.c
hiromimi@tachyon:~/dev/compile/8cc$ echo $?
1
メッセージもなく異常終了する
???
fork した子供プロセスがnull により停止していた
// Regular struct member
if (mem->name->len == tok->len && !strncmp(mem->name->loc, tok->loc, tok->len)) {
*rest = tok->next;
return mem;
}
}
ここの mem->name がNULL だった.
次のテストケースで再現できる. .sval = "1" が未実装.
typedef struct {
//bool space; // true if the token has a leading space
int space; // true if the token has a leading space
//bool bol; // true if the token is at the beginning of a line
int bol; // true if the token is at the beginning of a line
// 構造体中にboolが入るとだめ
union { struct { char *sval; }; };
} Token;
int main() {
((Token){ .sval = "1" });
printf("OK\n");
return 0;
}
typedef struct __builtin_va_list va_list; としてみると:
../chibicc/chibicc -o sk2cc vector.c string.c map.c binary.c error.c lex.c cpp.c parse.c sema.c gen.c cc.c as_error.c as_lex.c as_parse.c as_sema.c as_encode.c as_gen.c as.c main.c
binary.c:21: va_list ap;
^ variable has incomplete type
- gccと他のコンパイラでの間の内部実装の違いがこんなところに現れるのだなあ
そのあと、いろいろとやったところビルドは通せた。diffは以下の通り。
diff --git a/Makefile b/Makefile
index f5be62d..3eae4f5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,7 @@
-CC = gcc
-CFLAGS = -std=c11 --pedantic-errors -Wall -Wstrict-prototypes -g
+#CC = gcc
+#CFLAGS = -std=c11 --pedantic-errors -Wall -Wstrict-prototypes -g -Wextra
+CC=../chibicc/chibicc
+CFLAGS=
HEADERS = \
string.h vector.h map.h binary.h \
diff --git a/sk2cc.h b/sk2cc.h
index 38f715f..7c61da6 100644
--- a/sk2cc.h
+++ b/sk2cc.h
@@ -30,11 +30,14 @@ typedef unsigned long long size_t;
#define noreturn _Noreturn
// stdarg.h
+#include <stdarg.h>
+/*
#define va_start __builtin_va_start
#define va_arg __builtin_va_arg
#define va_end __builtin_va_end
typedef __builtin_va_list va_list;
+*/
// stdint.h
typedef long int intptr_t;