summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-04-03 15:39:03 -0700
committerGitHub <noreply@github.com>2023-04-03 15:39:03 -0700
commit68fd23453b2e2f7de0fa2e739ca4dee29152d0c0 (patch)
tree9e88659f485a01be8ec1ff4d2b80c2f2cfb4caf8 /src
parent382671ba0f673dd5da6bcaf6756fc43a518a41f6 (diff)
downloadbinaryen-68fd23453b2e2f7de0fa2e739ca4dee29152d0c0.tar.gz
binaryen-68fd23453b2e2f7de0fa2e739ca4dee29152d0c0.tar.bz2
binaryen-68fd23453b2e2f7de0fa2e739ca4dee29152d0c0.zip
[Wasm GC] Avoid refining in TypeUpdating unreachability propagation (#5616)
That code should only propagate unreachability, and not refine. If it refines when we call finalize() then other code around it might end up invalid (as it could be partially refined; see testcase).
Diffstat (limited to 'src')
-rw-r--r--src/ir/type-updating.h18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h
index d224f93dc..160934da1 100644
--- a/src/ir/type-updating.h
+++ b/src/ir/type-updating.h
@@ -248,14 +248,22 @@ struct TypeUpdater
return; // did not turn
}
} else if (auto* iff = curr->dynCast<If>()) {
- // may not be unreachable if just one side is
+ // We only want to change a concrete type to unreachable here, so undo
+ // anything else. Other changes can be a problem, like refining the type
+ // of an if for GC-using code, as the code all around us only assumes we
+ // are propagating unreachability and not doing a full refinalize.
+ auto old = iff->type;
iff->finalize();
if (curr->type != Type::unreachable) {
+ iff->type = old;
return; // did not turn
}
} else if (auto* tryy = curr->dynCast<Try>()) {
+ // See comment on If, above.
+ auto old = tryy->type;
tryy->finalize();
if (curr->type != Type::unreachable) {
+ tryy->type = old;
return; // did not turn
}
} else {
@@ -303,9 +311,13 @@ struct TypeUpdater
if (!curr->type.isConcrete()) {
return; // nothing concrete to change to unreachable
}
+ // See comment in propagateTypesUp() for If regarding restoring the type.
+ auto old = curr->type;
curr->finalize();
if (curr->type == Type::unreachable) {
propagateTypesUp(curr);
+ } else {
+ curr->type = old;
}
}
@@ -313,9 +325,13 @@ struct TypeUpdater
if (!curr->type.isConcrete()) {
return; // nothing concrete to change to unreachable
}
+ // See comment in propagateTypesUp() for Try regarding restoring the type.
+ auto old = curr->type;
curr->finalize();
if (curr->type == Type::unreachable) {
propagateTypesUp(curr);
+ } else {
+ curr->type = old;
}
}