summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2022-11-29 14:42:41 -0600
committerGitHub <noreply@github.com>2022-11-29 20:42:41 +0000
commit5a58d1132feebb902c30cb95b1f74673e490ad52 (patch)
tree993032d997c6f00ddbd66e4cd90b2ae7e0af55f2 /src
parent83cceaca5c9ce53ba4115aa732e7196db67bc493 (diff)
downloadbinaryen-5a58d1132feebb902c30cb95b1f74673e490ad52.tar.gz
binaryen-5a58d1132feebb902c30cb95b1f74673e490ad52.tar.bz2
binaryen-5a58d1132feebb902c30cb95b1f74673e490ad52.zip
Fix validation and inlining bugs (#5301)
Inlining had a bug where it gave return_calls in inlined callees concrete types even when they should have remained unreachable. This bug flew under the radar because validation had a bug where it allowed expressions to have concrete types when they should have been unreachable. The fuzzer found this bug by adding another pass after inlining where the unexpected types caused an assertion failure. Fix the bugs and add a test that would have triggered the inlining bug. Unfortunately the test would have also passed before this change due to the validation bug, but it's better than nothing. Fixes #5294.
Diffstat (limited to 'src')
-rw-r--r--src/passes/Inlining.cpp4
-rw-r--r--src/wasm/wasm-validator.cpp7
2 files changed, 8 insertions, 3 deletions
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index 0c95dc4b4..25993c7ec 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -275,7 +275,9 @@ struct Updater : public PostWalker<Updater> {
}
curr->isReturn = false;
curr->type = results;
- if (curr->type.isConcrete()) {
+ // There might still be unreachable children causing this to be unreachable.
+ curr->finalize();
+ if (results.isConcrete()) {
replaceCurrent(builder->makeBreak(returnName, curr));
} else {
replaceCurrent(builder->blockify(curr, builder->makeBreak(returnName)));
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 7a4bb6a97..ba8712d35 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -3074,8 +3074,11 @@ static void validateBinaryenIR(Module& wasm, ValidationInfo& info) {
bool validControlFlowStructureChange =
Properties::isControlFlowStructure(curr) && oldType.isConcrete() &&
newType == Type::unreachable;
- if (!Type::isSubType(newType, oldType) &&
- !validControlFlowStructureChange) {
+ // It's ok in general for types to get refined as long as they don't
+ // become unreachable.
+ bool validRefinement =
+ Type::isSubType(newType, oldType) && newType != Type::unreachable;
+ if (!validRefinement && !validControlFlowStructureChange) {
std::ostringstream ss;
ss << "stale type found in " << scope << " on " << curr
<< "\n(marked as " << oldType << ", should be " << newType