diff options
Diffstat (limited to 'src/ir/effects.h')
-rw-r--r-- | src/ir/effects.h | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h index fee8b3441..716624d64 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -431,6 +431,14 @@ private: self->pushTask(doStartTry, currp); return; } + if (auto* tryTable = curr->dynCast<TryTable>()) { + // We need to increment try depth before starting. + self->pushTask(doEndTryTable, currp); + self->pushTask(doVisitTryTable, currp); + self->pushTask(scan, &tryTable->body); + self->pushTask(doStartTryTable, currp); + return; + } PostWalker<InternalAnalyzer, OverriddenVisitor<InternalAnalyzer>>::scan( self, currp); } @@ -472,6 +480,24 @@ private: self->parent.catchDepth--; } + static void doStartTryTable(InternalAnalyzer* self, Expression** currp) { + auto* curr = (*currp)->cast<TryTable>(); + // We only count 'try_table's with a 'catch_all' because instructions + // within a 'try_table' without a 'catch_all' can still throw outside of + // the try. + if (curr->hasCatchAll()) { + self->parent.tryDepth++; + } + } + + static void doEndTryTable(InternalAnalyzer* self, Expression** currp) { + auto* curr = (*currp)->cast<TryTable>(); + if (curr->hasCatchAll()) { + assert(self->parent.tryDepth > 0 && "try depth cannot be negative"); + self->parent.tryDepth--; + } + } + void visitBlock(Block* curr) { if (curr->name.is()) { parent.breakTargets.erase(curr->name); // these were internal breaks |