diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-10-04 20:05:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-04 20:05:45 -0700 |
commit | 45ba1270e8d99c0c7fdc008c0db7c9d7fa0a4f38 (patch) | |
tree | 62ff9e2320b4b5c33b8a57f7ed3f85dd97a1e1d1 /src | |
parent | 4e1667aa3454f56b3e96df674c504cb16366b628 (diff) | |
download | binaryen-45ba1270e8d99c0c7fdc008c0db7c9d7fa0a4f38.tar.gz binaryen-45ba1270e8d99c0c7fdc008c0db7c9d7fa0a4f38.tar.bz2 binaryen-45ba1270e8d99c0c7fdc008c0db7c9d7fa0a4f38.zip |
DCE bugfix (#736)
* fix a dce bug where it is invalid to truncate a block if it leaves a final element with a bad type (wasm doesn't always allow removing unreachable code)
* add wast pass fuzzer
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/DeadCodeElimination.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp index b30b8ffbd..c2799f13a 100644 --- a/src/passes/DeadCodeElimination.cpp +++ b/src/passes/DeadCodeElimination.cpp @@ -110,12 +110,23 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination, V Index i = self->blockStack.back(); self->blockStack.back()++; if (!self->reachable) { - // control flow ended in the middle of the block + // control flow ended in the middle of the block, so we can truncate the rest. // note that we still visit the rest, so if we already truncated, do not lengthen. // note that it is ok that we visit the others even though the list was shortened; // our arena vectors leave things as they are when shrinking. if (block->list.size() > i + 1) { - block->list.resize(i + 1); + // but note that it is not legal to truncate a block if it leaves a bad last element, + // given the wasm type rules. For example, if the last element is a return, then + // the block doesn't care about it for type checking purposes, but if removing + // it would leave an element with type none as the last, that could be a problem, + // see https://github.com/WebAssembly/spec/issues/355 + if (!(isConcreteWasmType(block->type) && block->list[i]->type == none)) { + block->list.resize(i + 1); + // note that we do *not* finalize here. it is incorrect to re-finalize a block + // after removing elements, as it may no longer have branches to it that would + // determine its type, so re-finalizing would just wipe out an existing type + // that it had. + } } } } |