From 2ab19d9ac528ff11fa14b184a84c92e72d5b0163 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 22 Apr 2022 10:42:43 -0700 Subject: [NominalFuzzing] Fix getHeapTypeCounts() on unreachable casts (#4609) The cast instruction may be unreachable but the intended type for the cast still needs to be collected. Otherwise we end up with problems both during optimizations that look at heap types and in printing (which will use the heap type in code but not declare it). Diff without whitespace is much smaller: this just moves code around so that we can use a template to avoid code duplication. The actual change is just to scan ->intendedType unconditionally, and not ignore it if the cast is unreachable. --- src/ir/module-utils.cpp | 106 ++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 53 deletions(-) (limited to 'src/ir/module-utils.cpp') diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index b5d0d7d48..a061782f9 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -42,65 +42,65 @@ struct Counts : public InsertOrderedMap { } }; -Counts getHeapTypeCounts(Module& wasm) { - struct CodeScanner - : PostWalker> { - Counts& counts; +struct CodeScanner + : PostWalker> { + Counts& counts; - CodeScanner(Module& wasm, Counts& counts) : counts(counts) { - setModule(&wasm); - } + CodeScanner(Module& wasm, Counts& counts) : counts(counts) { + setModule(&wasm); + } - void visitExpression(Expression* curr) { - if (auto* call = curr->dynCast()) { - counts.note(call->heapType); - } else if (curr->is()) { + void visitExpression(Expression* curr) { + if (auto* call = curr->dynCast()) { + counts.note(call->heapType); + } else if (curr->is()) { + counts.note(curr->type); + } else if (curr->is() || curr->is()) { + counts.note(curr->type.getRtt().heapType); + } else if (auto* make = curr->dynCast()) { + handleMake(make); + } else if (auto* make = curr->dynCast()) { + handleMake(make); + } else if (auto* make = curr->dynCast()) { + handleMake(make); + } else if (auto* cast = curr->dynCast()) { + handleCast(cast); + } else if (auto* cast = curr->dynCast()) { + handleCast(cast); + } else if (auto* cast = curr->dynCast()) { + if (cast->op == BrOnCast || cast->op == BrOnCastFail) { + handleCast(cast); + } + } else if (auto* get = curr->dynCast()) { + counts.note(get->ref->type); + } else if (auto* set = curr->dynCast()) { + counts.note(set->ref->type); + } else if (Properties::isControlFlowStructure(curr)) { + if (curr->type.isTuple()) { + // TODO: Allow control flow to have input types as well + counts.note(Signature(Type::none, curr->type)); + } else { counts.note(curr->type); - } else if (curr->is() || curr->is()) { - counts.note(curr->type.getRtt().heapType); - } else if (auto* make = curr->dynCast()) { - // Some operations emit a HeapType in the binary format, if they are - // static and not dynamic (if dynamic, the RTT provides the heap type). - if (!make->rtt && make->type != Type::unreachable) { - counts.note(make->type.getHeapType()); - } - } else if (auto* make = curr->dynCast()) { - if (!make->rtt && make->type != Type::unreachable) { - counts.note(make->type.getHeapType()); - } - } else if (auto* make = curr->dynCast()) { - if (!make->rtt && make->type != Type::unreachable) { - counts.note(make->type.getHeapType()); - } - } else if (auto* cast = curr->dynCast()) { - if (!cast->rtt && cast->type != Type::unreachable) { - counts.note(cast->getIntendedType()); - } - } else if (auto* cast = curr->dynCast()) { - if (!cast->rtt && cast->type != Type::unreachable) { - counts.note(cast->getIntendedType()); - } - } else if (auto* cast = curr->dynCast()) { - if (cast->op == BrOnCast || cast->op == BrOnCastFail) { - if (!cast->rtt && cast->type != Type::unreachable) { - counts.note(cast->getIntendedType()); - } - } - } else if (auto* get = curr->dynCast()) { - counts.note(get->ref->type); - } else if (auto* set = curr->dynCast()) { - counts.note(set->ref->type); - } else if (Properties::isControlFlowStructure(curr)) { - if (curr->type.isTuple()) { - // TODO: Allow control flow to have input types as well - counts.note(Signature(Type::none, curr->type)); - } else { - counts.note(curr->type); - } } } - }; + } + + template void handleMake(T* curr) { + if (!curr->rtt && curr->type != Type::unreachable) { + counts.note(curr->type.getHeapType()); + } + } + template void handleCast(T* curr) { + // Some operations emit a HeapType in the binary format, if they are + // static and not dynamic (if dynamic, the RTT provides the heap type). + if (!curr->rtt) { + counts.note(curr->intendedType); + } + } +}; + +Counts getHeapTypeCounts(Module& wasm) { // Collect module-level info. Counts counts; CodeScanner(wasm, counts).walkModuleCode(&wasm); -- cgit v1.2.3