summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-05-20 10:50:02 -0700
committerGitHub <noreply@github.com>2017-05-20 10:50:02 -0700
commit9e0958982d2044949746c2d8290dbc0368546ebf (patch)
tree40baee2d19419d76ff904b79b6146be980d5b287
parent2ddb7cb1f45cf9aeef90ec5c8000a2d279f0302b (diff)
downloadbinaryen-9e0958982d2044949746c2d8290dbc0368546ebf.tar.gz
binaryen-9e0958982d2044949746c2d8290dbc0368546ebf.tar.bz2
binaryen-9e0958982d2044949746c2d8290dbc0368546ebf.zip
afl-fuzz bug fixes (#1018)
* values cannot flow through an if without an else, they never return a value * check pass tests in pass-debug mode too * add missing finalization in binary reading
-rwxr-xr-xcheck.py16
-rw-r--r--src/passes/RemoveUnusedBrs.cpp3
-rw-r--r--src/wasm/wasm-binary.cpp4
-rw-r--r--test/passes/flatten-control-flow.bin.txt239
-rw-r--r--test/passes/flatten-control-flow.wasmbin0 -> 458 bytes
-rw-r--r--test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt22
-rw-r--r--test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast29
7 files changed, 312 insertions, 1 deletions
diff --git a/check.py b/check.py
index 345a3b302..35f5bb628 100755
--- a/check.py
+++ b/check.py
@@ -85,10 +85,24 @@ for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'passes'))):
assert len(asserts) == 0
with open('split.wast', 'w') as o: o.write(module)
cmd = WASM_OPT + opts + ['split.wast', '--print']
- actual += run_command(cmd)
+ curr = run_command(cmd)
+ actual += curr
# also check debug mode output is valid
debugged = run_command(cmd + ['--debug'], stderr=subprocess.PIPE)
fail_if_not_contained(actual, debugged)
+ # also check pass-debug mode
+ old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
+ try:
+ os.environ['BINARYEN_PASS_DEBUG'] = '1'
+ pass_debug = run_command(cmd)
+ fail_if_not_identical(curr, pass_debug)
+ finally:
+ if old_pass_debug is not None:
+ os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
+ else:
+ if 'BINARYEN_PASS_DEBUG' in os.environ:
+ del os.environ['BINARYEN_PASS_DEBUG']
+
fail_if_not_identical(actual, open(os.path.join('test', 'passes', passname + ('.bin' if binary else '') + '.txt'), 'rb').read())
print '[ checking asm2wasm testcases... ]\n'
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 4273b9f63..1fa996ae6 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -84,6 +84,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
flows.push_back(flow);
}
self->ifStack.pop_back();
+ } else {
+ // if without else stops the flow of values
+ self->valueCanFlow = false;
}
} else if (curr->is<Block>()) {
// any breaks flowing to here are unnecessary, as we get here anyhow
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 6448615a5..65c6f2a21 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1800,6 +1800,7 @@ void WasmBinaryBuilder::visitSwitch(Switch *curr) {
curr->default_ = defaultTarget.name;
if (debug) std::cerr << "default: "<< curr->default_<<std::endl;
if (defaultTarget.arity) curr->value = popNonVoidExpression();
+ curr->finalize();
}
Expression* WasmBinaryBuilder::visitCall() {
@@ -1862,6 +1863,7 @@ void WasmBinaryBuilder::visitGetLocal(GetLocal *curr) {
throw ParseException("bad get_local index");
}
curr->type = currFunction->getLocalType(curr->index);
+ curr->finalize();
}
void WasmBinaryBuilder::visitSetLocal(SetLocal *curr, uint8_t code) {
@@ -2034,6 +2036,7 @@ bool WasmBinaryBuilder::maybeVisitUnary(Expression*& out, uint8_t code) {
}
if (debug) std::cerr << "zz node: Unary" << std::endl;
curr->value = popNonVoidExpression();
+ curr->finalize();
out = curr;
return true;
}
@@ -2116,6 +2119,7 @@ void WasmBinaryBuilder::visitReturn(Return *curr) {
if (currFunction->result != none) {
curr->value = popNonVoidExpression();
}
+ curr->finalize();
}
bool WasmBinaryBuilder::maybeVisitHost(Expression*& out, uint8_t code) {
diff --git a/test/passes/flatten-control-flow.bin.txt b/test/passes/flatten-control-flow.bin.txt
new file mode 100644
index 000000000..9b33f976e
--- /dev/null
+++ b/test/passes/flatten-control-flow.bin.txt
@@ -0,0 +1,239 @@
+(module
+ (type $0 (func (result i32)))
+ (type $1 (func (result i64)))
+ (type $2 (func (result f32)))
+ (type $3 (func (result f64)))
+ (type $4 (func (param i32) (result i32)))
+ (type $5 (func (param i64) (result i64)))
+ (type $6 (func (param f32) (result f32)))
+ (type $7 (func (param f64) (result f64)))
+ (type $8 (func (param i64 f32 f64 i32 i32)))
+ (type $9 (func (param i64 f32 f64 i32 i32) (result f64)))
+ (memory $0 0)
+ (export "type-local-i32" (func $0))
+ (export "type-local-i64" (func $1))
+ (export "type-local-f32" (func $2))
+ (export "type-local-f64" (func $3))
+ (export "type-param-i32" (func $4))
+ (export "type-param-i64" (func $5))
+ (export "tÿÿe-param-f32" (func $6))
+ (export "type-param-f64" (func $7))
+ (export "type-mixed" (func $8))
+ (export "read" (func $9))
+ (func $0 (type $0) (result i32)
+ (local $var$0 i32)
+ (local $1 i32)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $1 (type $1) (result i64)
+ (local $var$0 i64)
+ (local $1 i64)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $2 (type $2) (result f32)
+ (local $var$0 f32)
+ (local $1 f32)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $3 (type $3) (result f64)
+ (local $var$0 f64)
+ (local $1 f64)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $4 (type $4) (param $var$0 i32) (result i32)
+ (local $1 i32)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $5 (type $5) (param $var$0 i64) (result i64)
+ (local $1 i64)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $6 (type $6) (param $var$0 f32) (result f32)
+ (local $1 f32)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $7 (type $7) (param $var$0 f64) (result f64)
+ (local $1 f64)
+ (block
+ (set_local $1
+ (get_local $var$0)
+ )
+ )
+ (return
+ (get_local $1)
+ )
+ )
+ (func $8 (type $8) (param $var$0 i64) (param $var$1 f32) (param $var$2 f64) (param $var$3 i32) (param $var$4 i32)
+ (local $var$5 i64)
+ (local $var$6 i64)
+ (local $var$7 f32)
+ (local $var$8 f64)
+ (block $label$0
+ (nop)
+ (block
+ (block
+ (unreachable)
+ )
+ )
+ (drop
+ (f32.neg
+ (get_local $var$1)
+ )
+ )
+ (drop
+ (f64.neg
+ (get_local $var$2)
+ )
+ )
+ (drop
+ (i32.eqz
+ (get_local $var$3)
+ )
+ )
+ (drop
+ (i32.eqz
+ (get_local $var$4)
+ )
+ )
+ (drop
+ (f32.neg
+ (get_local $var$7)
+ )
+ )
+ (drop
+ (i64.eqz
+ (get_local $var$5)
+ )
+ )
+ (drop
+ (i64.eqz
+ (get_local $var$6)
+ )
+ )
+ (drop
+ (f64.neg
+ (get_local $var$8)
+ )
+ )
+ )
+ )
+ (func $9 (type $9) (param $var$0 i64) (param $var$1 f32) (param $var$2 f64) (param $var$3 i32) (param $var$4 i32) (result f64)
+ (local $var$5 i64)
+ (local $var$6 i64)
+ (local $var$7 f32)
+ (local $var$8 f64)
+ (local $9 f64)
+ (local $10 f64)
+ (block
+ (block
+ (block $label$0
+ (set_local $var$7
+ (f32.const 5.5)
+ )
+ (set_local $var$5
+ (i64.const 6)
+ )
+ (set_local $var$8
+ (f64.const 8)
+ )
+ (set_local $9
+ (f64.add
+ (f64.convert_u/i64
+ (get_local $var$0)
+ )
+ (f64.add
+ (f64.promote/f32
+ (get_local $var$1)
+ )
+ (f64.add
+ (get_local $var$2)
+ (f64.add
+ (f64.convert_u/i32
+ (get_local $var$3)
+ )
+ (f64.add
+ (f64.convert_s/i32
+ (get_local $var$4)
+ )
+ (f64.add
+ (f64.promote/f32
+ (get_local $var$7)
+ )
+ (f64.add
+ (f64.convert_u/i64
+ (get_local $var$5)
+ )
+ (f64.add
+ (f64.convert_u/i64
+ (get_local $var$6)
+ )
+ (get_local $var$8)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (set_local $10
+ (get_local $9)
+ )
+ )
+ )
+ (return
+ (get_local $10)
+ )
+ )
+)
diff --git a/test/passes/flatten-control-flow.wasm b/test/passes/flatten-control-flow.wasm
new file mode 100644
index 000000000..0ba6a86fe
--- /dev/null
+++ b/test/passes/flatten-control-flow.wasm
Binary files differ
diff --git a/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt
new file mode 100644
index 000000000..e2d4f13a9
--- /dev/null
+++ b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt
@@ -0,0 +1,22 @@
+(module
+ (type $0 (func (param i32) (result f64)))
+ (global $global$3 (mut f64) (f64.const 0))
+ (memory $0 0)
+ (func $1 (type $0) (param $x i32) (result f64)
+ (local $var$0 f64)
+ (block $label$0
+ (set_local $var$0
+ (f64.const 0)
+ )
+ (return
+ (f64.const -3.4)
+ )
+ (if
+ (get_local $x)
+ (return
+ (f64.const 5.6)
+ )
+ )
+ )
+ )
+)
diff --git a/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast
new file mode 100644
index 000000000..5dfbfa102
--- /dev/null
+++ b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast
@@ -0,0 +1,29 @@
+(module
+ (global $global$3 (mut f64) (f64.const 0))
+ (func $1 (param $x i32) (result f64)
+ (local $var$0 f64)
+ (block $label$0
+ (set_local $var$0
+ (f64.const 0)
+ )
+ (if
+ (i32.gt_s
+ (i32.const 9)
+ (i32.const 0)
+ )
+ (return
+ (f64.const -3.4)
+ )
+ )
+ (if
+ (get_local $x)
+ (return
+ (f64.const 5.6)
+ )
+ )
+ (return
+ (f64.const 1.2)
+ )
+ )
+ )
+)