diff options
| author | 2025-11-23 19:38:38 +0100 | |
|---|---|---|
| committer | 2025-11-23 19:38:38 +0100 | |
| commit | 0b77ae0eda8d3abca659f816040021a82a456e81 (patch) | |
| tree | de72d56c0d0f3efb88faba88129d7825973bace8 /ir | |
| parent | a86bbfc553433e377e48f9e26c90bcc5b4fe0263 (diff) | |
c: check actual reachability for non-void func may not return value
Diffstat (limited to 'ir')
| -rw-r--r-- | ir/ir.c | 21 | ||||
| -rw-r--r-- | ir/ir.h | 1 |
2 files changed, 22 insertions, 0 deletions
@@ -451,6 +451,27 @@ numberinstrs(struct function *fn) } while ((blk = blk->lnext) != fn->entry); } +static bool +reachablerec(struct function *fn, struct block *blk) +{ + if (blk == fn->entry) return 1; + markvisited(blk); + if (blk->npred == 1 && !wasvisited(blkpred(blk, 0))) + return reachablerec(fn, blkpred(blk, 0)); + else for (int i = 0; i < blk->npred; ++i) { + struct block *p = blkpred(blk, i); + if (!wasvisited(p) && reachablerec(fn, p)) return 1; + } + return 0; +} + +bool +blkreachable(struct function *fn, struct block *blk) +{ + startbbvisit(); + return reachablerec(fn, blk); +} + /* require use */ void replcuses(union ref from, union ref to) @@ -277,6 +277,7 @@ void fillblkids(struct function *); #define wasvisited(blk) ((blk)->visit == visitmark) #define markvisited(blk) ((blk)->visit = visitmark) void numberinstrs(struct function *); +bool blkreachable(struct function *fn, struct block *blk); /** builder.c **/ union ref irbinop(struct function *, enum op, enum irclass, union ref lhs, union ref rhs); |