diff options
author | Alon Zakai <azakai@google.com> | 2023-04-03 15:39:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-03 15:39:03 -0700 |
commit | 68fd23453b2e2f7de0fa2e739ca4dee29152d0c0 (patch) | |
tree | 9e88659f485a01be8ec1ff4d2b80c2f2cfb4caf8 /src | |
parent | 382671ba0f673dd5da6bcaf6756fc43a518a41f6 (diff) | |
download | binaryen-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.h | 18 |
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; } } |