summaryrefslogtreecommitdiff
path: root/src/ir/module-utils.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-04-22 10:42:43 -0700
committerGitHub <noreply@github.com>2022-04-22 10:42:43 -0700
commit2ab19d9ac528ff11fa14b184a84c92e72d5b0163 (patch)
tree015d0a00203a1fc08c95e795b2e1c9bc68817050 /src/ir/module-utils.cpp
parent6000629ae7cc2962483cd0d7ae4a770c8f2a34a0 (diff)
downloadbinaryen-2ab19d9ac528ff11fa14b184a84c92e72d5b0163.tar.gz
binaryen-2ab19d9ac528ff11fa14b184a84c92e72d5b0163.tar.bz2
binaryen-2ab19d9ac528ff11fa14b184a84c92e72d5b0163.zip
[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.
Diffstat (limited to 'src/ir/module-utils.cpp')
-rw-r--r--src/ir/module-utils.cpp106
1 files changed, 53 insertions, 53 deletions
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<HeapType, size_t> {
}
};
-Counts getHeapTypeCounts(Module& wasm) {
- struct CodeScanner
- : PostWalker<CodeScanner, UnifiedExpressionVisitor<CodeScanner>> {
- Counts& counts;
+struct CodeScanner
+ : PostWalker<CodeScanner, UnifiedExpressionVisitor<CodeScanner>> {
+ 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<CallIndirect>()) {
- counts.note(call->heapType);
- } else if (curr->is<RefNull>()) {
+ void visitExpression(Expression* curr) {
+ if (auto* call = curr->dynCast<CallIndirect>()) {
+ counts.note(call->heapType);
+ } else if (curr->is<RefNull>()) {
+ counts.note(curr->type);
+ } else if (curr->is<RttCanon>() || curr->is<RttSub>()) {
+ counts.note(curr->type.getRtt().heapType);
+ } else if (auto* make = curr->dynCast<StructNew>()) {
+ handleMake(make);
+ } else if (auto* make = curr->dynCast<ArrayNew>()) {
+ handleMake(make);
+ } else if (auto* make = curr->dynCast<ArrayInit>()) {
+ handleMake(make);
+ } else if (auto* cast = curr->dynCast<RefCast>()) {
+ handleCast(cast);
+ } else if (auto* cast = curr->dynCast<RefTest>()) {
+ handleCast(cast);
+ } else if (auto* cast = curr->dynCast<BrOn>()) {
+ if (cast->op == BrOnCast || cast->op == BrOnCastFail) {
+ handleCast(cast);
+ }
+ } else if (auto* get = curr->dynCast<StructGet>()) {
+ counts.note(get->ref->type);
+ } else if (auto* set = curr->dynCast<StructSet>()) {
+ 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<RttCanon>() || curr->is<RttSub>()) {
- counts.note(curr->type.getRtt().heapType);
- } else if (auto* make = curr->dynCast<StructNew>()) {
- // 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<ArrayNew>()) {
- if (!make->rtt && make->type != Type::unreachable) {
- counts.note(make->type.getHeapType());
- }
- } else if (auto* make = curr->dynCast<ArrayInit>()) {
- if (!make->rtt && make->type != Type::unreachable) {
- counts.note(make->type.getHeapType());
- }
- } else if (auto* cast = curr->dynCast<RefCast>()) {
- if (!cast->rtt && cast->type != Type::unreachable) {
- counts.note(cast->getIntendedType());
- }
- } else if (auto* cast = curr->dynCast<RefTest>()) {
- if (!cast->rtt && cast->type != Type::unreachable) {
- counts.note(cast->getIntendedType());
- }
- } else if (auto* cast = curr->dynCast<BrOn>()) {
- if (cast->op == BrOnCast || cast->op == BrOnCastFail) {
- if (!cast->rtt && cast->type != Type::unreachable) {
- counts.note(cast->getIntendedType());
- }
- }
- } else if (auto* get = curr->dynCast<StructGet>()) {
- counts.note(get->ref->type);
- } else if (auto* set = curr->dynCast<StructSet>()) {
- 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<typename T> void handleMake(T* curr) {
+ if (!curr->rtt && curr->type != Type::unreachable) {
+ counts.note(curr->type.getHeapType());
+ }
+ }
+ template<typename T> 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);