Skip to content

Commit 4d0b963

Browse files
committed
Fix self-hosting compilation errors
This commit resolves critical issues preventing shecc from compiling itself, enabling successful multi-stage bootstrapping. 1. Format string error in src/ssa.c:1138 - changed %s to %d for integer subscript field 2. Added null checks for func->bbs throughout codebase to handle function declarations without bodies, preventing segfaults in SSA and optimization passes 3. Split global variable continuation declarations that shecc doesn't support (e.g., "int a, b;" must be "int a; int b;")
1 parent b6dd21c commit 4d0b963

File tree

12 files changed

+140
-12
lines changed

12 files changed

+140
-12
lines changed

src/arch-lower.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
void arm_lower(void)
1818
{
1919
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
20+
/* Skip function declarations without bodies */
21+
if (!func->bbs)
22+
continue;
23+
2024
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
2125
for (ph2_ir_t *insn = bb->ph2_ir_list.head; insn;
2226
insn = insn->next) {
@@ -37,6 +41,10 @@ void arm_lower(void)
3741
void riscv_lower(void)
3842
{
3943
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
44+
/* Skip function declarations without bodies */
45+
if (!func->bbs)
46+
continue;
47+
4048
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
4149
for (ph2_ir_t *insn = bb->ph2_ir_list.head; insn;
4250
insn = insn->next) {

src/arm-codegen.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ void cfg_flatten(void)
151151
elf_offset += 32; /* 6 insns for main call + 2 for exit */
152152

153153
for (func = FUNC_LIST.head; func; func = func->next) {
154+
/* Skip function declarations without bodies */
155+
if (!func->bbs)
156+
continue;
157+
154158
/* reserve stack */
155159
ph2_ir_t *flatten_ir = add_ph2_ir(OP_define);
156160
flatten_ir->src0 = func->stack_size;

src/globals.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,19 @@ strbuf_t *SOURCE;
9191
hashmap_t *INCLUSION_MAP;
9292

9393
/* ELF sections */
94-
strbuf_t *elf_code, *elf_data;
94+
strbuf_t *elf_code;
95+
strbuf_t *elf_data;
9596
strbuf_t *elf_rodata;
9697
strbuf_t *elf_header;
9798
strbuf_t *elf_symtab;
9899
strbuf_t *elf_strtab;
99100
strbuf_t *elf_section;
100101
int elf_header_len = 0x54; /* ELF fixed: 0x34 + 1 * 0x20 */
101-
int elf_code_start, elf_data_start;
102+
int elf_code_start;
103+
int elf_data_start;
102104
int elf_rodata_start;
103-
int elf_bss_start, elf_bss_size;
105+
int elf_bss_start;
106+
int elf_bss_size;
104107

105108
/* Create a new arena block with given capacity.
106109
* @capacity: The capacity of the arena block. Must be positive.
@@ -347,7 +350,8 @@ bb_traversal_args_t *arena_alloc_traversal_args(void)
347350

348351
void arena_free(arena_t *arena)
349352
{
350-
arena_block_t *block = arena->head, *next;
353+
arena_block_t *block = arena->head;
354+
arena_block_t *next;
351355

352356
while (block) {
353357
next = block->next;
@@ -472,7 +476,9 @@ void hashmap_rehash(hashmap_t *map)
472476
}
473477

474478
for (int i = 0; i < old_cap; i++) {
475-
hashmap_node_t *cur = old_buckets[i], *next, *target_cur;
479+
hashmap_node_t *cur = old_buckets[i];
480+
hashmap_node_t *next;
481+
hashmap_node_t *target_cur;
476482

477483
while (cur) {
478484
next = cur->next;
@@ -1649,6 +1655,10 @@ void dump_insn(void)
16491655
printf("==<START OF INSN DUMP>==\n");
16501656

16511657
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1658+
/* Skip function declarations without bodies */
1659+
if (!func->bbs)
1660+
continue;
1661+
16521662
bool at_func_start = true;
16531663

16541664
printf("def %s", func->return_def.type->type_name);

src/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
int main(int argc, char *argv[])
5050
{
5151
bool libc = true;
52-
char *out = NULL, *in = NULL;
52+
char *out = NULL;
53+
char *in = NULL;
5354

5455
for (int i = 1; i < argc; i++) {
5556
if (!strcmp(argv[i], "--dump-ir"))

src/peephole.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,10 @@ bool triple_pattern_optimization(ph2_ir_t *ph2_ir)
878878
void peephole(void)
879879
{
880880
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
881+
/* Skip function declarations without bodies */
882+
if (!func->bbs)
883+
continue;
884+
881885
/* Local peephole optimizations on post-register-allocation IR */
882886
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
883887
for (ph2_ir_t *ir = bb->ph2_ir_list.head; ir; ir = ir->next) {

src/reg-alloc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,10 @@ void reg_alloc(void)
521521
}
522522

523523
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
524+
/* Skip function declarations without bodies */
525+
if (!func->bbs)
526+
continue;
527+
524528
func->visited++;
525529

526530
if (!strcmp(func->return_def.var_name, "main"))

src/riscv-codegen.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ void cfg_flatten(void)
127127
elf_offset += 24;
128128

129129
for (func = FUNC_LIST.head; func; func = func->next) {
130+
/* Skip function declarations without bodies */
131+
if (!func->bbs)
132+
continue;
133+
130134
/* reserve stack */
131135
ph2_ir_t *flatten_ir = add_ph2_ir(OP_define);
132136
flatten_ir->src0 = func->stack_size;

src/ssa.c

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ void build_rpo(void)
116116
{
117117
bb_traversal_args_t *args = arena_alloc_traversal_args();
118118
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
119+
/* Skip function declarations without bodies */
120+
if (!func->bbs)
121+
continue;
122+
119123
args->func = func;
120124
args->bb = func->bbs;
121125

@@ -158,6 +162,10 @@ basic_block_t *intersect(basic_block_t *i, basic_block_t *j)
158162
void build_idom(void)
159163
{
160164
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
165+
/* Skip function declarations without bodies */
166+
if (!func->bbs)
167+
continue;
168+
161169
bool changed;
162170

163171
func->bbs->idom = func->bbs;
@@ -230,6 +238,10 @@ void build_dom(void)
230238
{
231239
bb_traversal_args_t *args = arena_alloc_traversal_args();
232240
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
241+
/* Skip function declarations without bodies */
242+
if (!func->bbs)
243+
continue;
244+
233245
args->func = func;
234246
args->bb = func->bbs;
235247

@@ -264,6 +276,10 @@ void build_df(void)
264276
{
265277
bb_traversal_args_t *args = arena_alloc_traversal_args();
266278
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
279+
/* Skip function declarations without bodies */
280+
if (!func->bbs)
281+
continue;
282+
267283
args->func = func;
268284
args->bb = func->bbs;
269285

@@ -287,6 +303,10 @@ basic_block_t *reverse_intersect(basic_block_t *i, basic_block_t *j)
287303
void build_r_idom(void)
288304
{
289305
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
306+
/* Skip function declarations without bodies */
307+
if (!func->bbs)
308+
continue;
309+
290310
bool changed;
291311

292312
func->exit->r_idom = func->exit;
@@ -354,6 +374,10 @@ void build_rdom(void)
354374
{
355375
bb_traversal_args_t *args = arena_alloc_traversal_args();
356376
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
377+
/* Skip function declarations without bodies */
378+
if (!func->bbs)
379+
continue;
380+
357381
args->func = func;
358382
args->bb = func->exit;
359383

@@ -398,6 +422,10 @@ void build_rdf(void)
398422
{
399423
bb_traversal_args_t *args = arena_alloc_traversal_args();
400424
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
425+
/* Skip function declarations without bodies */
426+
if (!func->bbs)
427+
continue;
428+
401429
args->func = func;
402430
args->bb = func->exit;
403431

@@ -439,6 +467,10 @@ void use_chain_delete(use_chain_t *u, var_t *var)
439467
void use_chain_build(void)
440468
{
441469
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
470+
/* Skip function declarations without bodies */
471+
if (!func->bbs)
472+
continue;
473+
442474
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
443475
for (insn_t *i = bb->insn_list.head; i; i = i->next) {
444476
if (i->rs1)
@@ -545,6 +577,10 @@ void solve_globals(void)
545577
{
546578
bb_traversal_args_t *args = arena_alloc_traversal_args();
547579
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
580+
/* Skip function declarations without bodies */
581+
if (!func->bbs)
582+
continue;
583+
548584
args->func = func;
549585
args->bb = func->bbs;
550586

@@ -606,6 +642,10 @@ bool insert_phi_insn(basic_block_t *bb, var_t *var)
606642
void solve_phi_insertion(void)
607643
{
608644
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
645+
/* Skip function declarations without bodies */
646+
if (!func->bbs)
647+
continue;
648+
609649
for (symbol_t *sym = func->global_sym_list.head; sym; sym = sym->next) {
610650
var_t *var = sym->var;
611651

@@ -798,6 +838,10 @@ void bb_solve_phi_params(basic_block_t *bb)
798838
void solve_phi_params(void)
799839
{
800840
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
841+
/* Skip function declarations without bodies */
842+
if (!func->bbs)
843+
continue;
844+
801845
for (int i = 0; i < func->num_params; i++) {
802846
/* FIXME: Direct argument renaming in SSA construction phase may
803847
* interfere with later optimization passes
@@ -874,6 +918,10 @@ void unwind_phi(void)
874918
{
875919
bb_traversal_args_t *args = arena_alloc_traversal_args();
876920
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
921+
/* Skip function declarations without bodies */
922+
if (!func->bbs)
923+
continue;
924+
877925
args->func = func;
878926
args->bb = func->bbs;
879927

@@ -1135,7 +1183,7 @@ void bb_dump(FILE *fd, func_t *func, basic_block_t *bb)
11351183
break;
11361184
case OP_sign_ext:
11371185
sprintf(str,
1138-
"<%s<SUB>%s</SUB> := sign_ext %s<SUB>%d</SUB>, %d>",
1186+
"<%s<SUB>%d</SUB> := sign_ext %s<SUB>%d</SUB>, %d>",
11391187
insn->rd->var_name, insn->rd->subscript,
11401188
insn->rs1->var_name, insn->rs1->subscript, insn->sz);
11411189
break;
@@ -1180,6 +1228,10 @@ void dump_cfg(char name[])
11801228
fprintf(fd, "strict digraph CFG {\n");
11811229
fprintf(fd, "node [shape=box]\n");
11821230
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1231+
/* Skip function declarations without bodies */
1232+
if (!func->bbs)
1233+
continue;
1234+
11831235
func->visited++;
11841236
fprintf(fd, "subgraph cluster_%p {\n", func);
11851237
fprintf(fd, "label=\"%p (%s)\"\n", func, func->return_def.var_name);
@@ -1209,6 +1261,10 @@ void dump_dom(char name[])
12091261
fprintf(fd, "node [shape=box]\n");
12101262
fprintf(fd, "splines=polyline\n");
12111263
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1264+
/* Skip function declarations without bodies */
1265+
if (!func->bbs)
1266+
continue;
1267+
12121268
fprintf(fd, "subgraph cluster_%p {\n", func);
12131269
fprintf(fd, "label=\"%p\"\n", func);
12141270
dom_dump(fd, func->bbs);
@@ -1740,6 +1796,10 @@ void dce_sweep(void)
17401796
int total_eliminated = 0; /* Track effectiveness */
17411797

17421798
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1799+
/* Skip function declarations without bodies */
1800+
if (!func->bbs)
1801+
continue;
1802+
17431803
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
17441804
/* Skip unreachable blocks entirely */
17451805
if (is_block_unreachable(bb)) {
@@ -1812,17 +1872,30 @@ void optimize(void)
18121872
while (sccp_changed && sccp_iterations < 5) {
18131873
sccp_changed = false;
18141874
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1875+
/* Skip function declarations without bodies */
1876+
if (!func->bbs)
1877+
continue;
1878+
18151879
if (simple_sccp(func))
18161880
sccp_changed = true;
18171881
}
18181882
sccp_iterations++;
18191883
}
18201884

18211885
/* Run constant cast optimization for truncation */
1822-
for (func_t *func = FUNC_LIST.head; func; func = func->next)
1886+
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1887+
/* Skip function declarations without bodies */
1888+
if (!func->bbs)
1889+
continue;
1890+
18231891
optimize_constant_casts(func);
1892+
}
18241893

18251894
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1895+
/* Skip function declarations without bodies */
1896+
if (!func->bbs)
1897+
continue;
1898+
18261899
/* basic block level (control flow) optimizations */
18271900

18281901
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
@@ -2190,6 +2263,10 @@ void optimize(void)
21902263

21912264
/* Phi node optimization - eliminate trivial phi nodes */
21922265
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
2266+
/* Skip function declarations without bodies */
2267+
if (!func->bbs)
2268+
continue;
2269+
21932270
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
21942271
for (insn_t *insn = bb->insn_list.head; insn; insn = insn->next) {
21952272
if (insn->opcode == OP_phi && insn->phi_ops) {
@@ -2242,6 +2319,10 @@ void optimize(void)
22422319

22432320
/* Mark useful instructions */
22442321
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
2322+
/* Skip function declarations without bodies */
2323+
if (!func->bbs)
2324+
continue;
2325+
22452326
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
22462327
dce_insn(bb);
22472328
}
@@ -2286,6 +2367,10 @@ void build_reversed_rpo(void)
22862367
{
22872368
bb_traversal_args_t *args = arena_alloc_traversal_args();
22882369
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
2370+
/* Skip function declarations without bodies */
2371+
if (!func->bbs)
2372+
continue;
2373+
22892374
func->bb_cnt = 0;
22902375
args->func = func;
22912376
args->bb = func->exit;
@@ -2521,6 +2606,10 @@ void liveness_analysis(void)
25212606
{
25222607
bb_traversal_args_t *args = arena_alloc_traversal_args();
25232608
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
2609+
/* Skip function declarations without bodies */
2610+
if (!func->bbs)
2611+
continue;
2612+
25242613
args->func = func;
25252614
args->bb = func->bbs;
25262615

@@ -2535,6 +2624,10 @@ void liveness_analysis(void)
25352624
}
25362625

25372626
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
2627+
/* Skip function declarations without bodies */
2628+
if (!func->bbs)
2629+
continue;
2630+
25382631
basic_block_t *bb = func->exit;
25392632
bool changed;
25402633
do {

tests/snapshots/fib-arm.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/snapshots/fib-riscv.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)