summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-11-09 15:09:34 -0800
committerGitHub <noreply@github.com>2017-11-09 15:09:34 -0800
commit566e2c15016cbcf45dfa844ef2788ce27cdfab6f (patch)
tree645c96ac9e50e37d2d237cde747b1030f6501657
parent83f62325ac33706b1fcc589bc5ad6e290ed14d3f (diff)
downloadbinaryen-566e2c15016cbcf45dfa844ef2788ce27cdfab6f.tar.gz
binaryen-566e2c15016cbcf45dfa844ef2788ce27cdfab6f.tar.bz2
binaryen-566e2c15016cbcf45dfa844ef2788ce27cdfab6f.zip
Rereloop fuzz fix (#1259)
* fix relooper bug, ensure function body has right type, as relooper output does not flow stuff out, but wasm functions with a result do expect a flow value, so none is not an option. in other words, as the docs say, a relooper block must end with a terminator (return, unreachable, break, etc.) and not flow out.
-rw-r--r--src/passes/ReReloop.cpp12
-rw-r--r--test/passes/flatten_rereloop.txt82
-rw-r--r--test/passes/flatten_rereloop.wast24
-rw-r--r--test/passes/rereloop.txt39
4 files changed, 139 insertions, 18 deletions
diff --git a/src/passes/ReReloop.cpp b/src/passes/ReReloop.cpp
index 99e60a72f..ff1eec6b5 100644
--- a/src/passes/ReReloop.cpp
+++ b/src/passes/ReReloop.cpp
@@ -345,6 +345,18 @@ struct ReReloop final : public Pass {
auto temp = builder->addVar(function, i32);
CFG::RelooperBuilder builder(*module, temp);
function->body = relooper.Render(builder);
+ // if the function has a result, and the relooper emitted
+ // something that seems like it flows out without a value
+ // (but that path is never reached; it just has a br to it
+ // because of the relooper's boilerplate switch-handling
+ // code, for example, which could be optimized out later
+ // but isn't yet), then make sure it has a proper type
+ if (function->result != none && function->body->type == none) {
+ function->body = builder.makeSequence(
+ function->body,
+ builder.makeUnreachable()
+ );
+ }
}
// TODO: should this be in the relooper itself?
ReFinalize().walk(function->body);
diff --git a/test/passes/flatten_rereloop.txt b/test/passes/flatten_rereloop.txt
index ba5b6c67a..587124191 100644
--- a/test/passes/flatten_rereloop.txt
+++ b/test/passes/flatten_rereloop.txt
@@ -43,3 +43,85 @@
)
)
)
+(module
+ (type $0 (func (result i32)))
+ (memory $0 0)
+ (func $0 (; 0 ;) (type $0) (result i32)
+ (local $0 i32)
+ (local $1 i32)
+ (local $2 i32)
+ (block
+ (block
+ )
+ (block $switch$1$leave
+ (block $switch$1$default
+ (block $switch$1$case$5
+ (block $switch$1$case$4
+ (br_table $switch$1$case$5 $switch$1$case$4 $switch$1$default
+ (i32.const 0)
+ )
+ )
+ (block
+ (block
+ (block
+ (nop)
+ (unreachable)
+ )
+ )
+ )
+ )
+ (block
+ (block
+ (block
+ (nop)
+ (unreachable)
+ )
+ )
+ )
+ )
+ (block
+ (block
+ (block
+ (nop)
+ )
+ (block $switch$6$leave
+ (block $switch$6$default
+ (block $switch$6$case$3
+ (br_table $switch$6$case$3 $switch$6$default
+ (i32.const 1)
+ )
+ )
+ (block
+ (block
+ (block
+ (nop)
+ (unreachable)
+ )
+ )
+ )
+ )
+ (block
+ (block
+ (block
+ (nop)
+ (set_local $0
+ (i32.const 2)
+ )
+ (set_local $1
+ (get_local $0)
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ )
+ (unreachable)
+ )
+)
diff --git a/test/passes/flatten_rereloop.wast b/test/passes/flatten_rereloop.wast
index b575f9c55..2584b5146 100644
--- a/test/passes/flatten_rereloop.wast
+++ b/test/passes/flatten_rereloop.wast
@@ -9,4 +9,28 @@
(f64.const -nan:0xfffffd63e4e5a)
)
)
+(module
+ (func $0 (result i32)
+ (block $label$8
+ (block $label$9
+ (block $label$16
+ (block $label$18
+ (block $label$19
+ (br_table $label$18 $label$16 $label$19
+ (i32.const 0)
+ )
+ )
+ (br_table $label$9 $label$8
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (unreachable)
+ )
+ (unreachable)
+ )
+ (i32.const 2)
+ )
+)
diff --git a/test/passes/rereloop.txt b/test/passes/rereloop.txt
index b5750b16c..52f088594 100644
--- a/test/passes/rereloop.txt
+++ b/test/passes/rereloop.txt
@@ -713,20 +713,31 @@
(func $switcher-to-nowhere (; 13 ;) (type $2) (param $0 i32) (result i32)
(local $1 i32)
(block
- )
- (block $switch$1$leave
- (block $switch$1$default
- (block $switch$1$case$3
- (block $switch$1$case$4
- (br_table $switch$1$case$4 $switch$1$case$3 $switch$1$default
- (get_local $0)
+ (block
+ )
+ (block $switch$1$leave
+ (block $switch$1$default
+ (block $switch$1$case$3
+ (block $switch$1$case$4
+ (br_table $switch$1$case$4 $switch$1$case$3 $switch$1$default
+ (get_local $0)
+ )
+ )
+ (block
+ (block
+ (block
+ (return
+ (i32.const 1)
+ )
+ )
+ )
)
)
(block
(block
(block
(return
- (i32.const 1)
+ (i32.const 2)
)
)
)
@@ -736,22 +747,14 @@
(block
(block
(return
- (i32.const 2)
+ (i32.const 3)
)
)
)
)
)
- (block
- (block
- (block
- (return
- (i32.const 3)
- )
- )
- )
- )
)
+ (unreachable)
)
)
(module