Skip to content

Commit 72bacfd

Browse files
authored
Fix comparison of none and unreachable types (#2514)
Currently `none` and `unreachable` types are stored as the same empty `{}` in src/wasm/wasm-type.cpp. This makes `Type::operator<` incorrectly when given `none` and `unreachable`, because it expands both given types and lexicographically compare them, when both of the expanded vector will be empty. This was found by the fuzzer. This line in `Modder::visitExpression` tries to retrieve candidates of the same type. Because we can't really compare these two types, if you give `unreachable` as the key, candidates of `none` type can be returned. This generates incorrect code that ends up failing in validation in a very weird way. It was hard to generate a small testcase to trigger this part because it was found by generating fuzzed code from a random data file. But I guess this fix is pretty straightforward. Fixes #2512.
1 parent 42b61e3 commit 72bacfd

5 files changed

Lines changed: 963 additions & 544 deletions

File tree

src/wasm/wasm-type.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ std::vector<std::unique_ptr<std::vector<Type>>> typeLists = [] {
5656
};
5757

5858
add({});
59-
add({});
59+
add({Type::unreachable});
6060
add({Type::i32});
6161
add({Type::i64});
6262
add({Type::f32});
@@ -69,7 +69,7 @@ std::vector<std::unique_ptr<std::vector<Type>>> typeLists = [] {
6969

7070
std::unordered_map<std::vector<Type>, uint32_t> indices = {
7171
{{}, Type::none},
72-
{{}, Type::unreachable},
72+
{{Type::unreachable}, Type::unreachable},
7373
{{Type::i32}, Type::i32},
7474
{{Type::i64}, Type::i64},
7575
{{Type::f32}, Type::f32},

test/binaryen.js/kitchen-sink.js.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// BinaryenTypeNone: 0
22
// []
33
// BinaryenTypeUnreachable: 1
4-
// []
4+
// [ 1 ]
55
// BinaryenTypeInt32: 2
66
// [ 2 ]
77
// BinaryenTypeInt64: 3
@@ -10106,7 +10106,7 @@ optimized:
1010610106
// BinaryenTypeNone: 0
1010710107
// []
1010810108
// BinaryenTypeUnreachable: 1
10109-
// []
10109+
// [ 1 ]
1011010110
// BinaryenTypeInt32: 2
1011110111
// [ 2 ]
1011210112
// BinaryenTypeInt64: 3

test/example/c-api-kitchen-sink.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ void test_types() {
159159

160160
BinaryenType unreachable = BinaryenTypeUnreachable();
161161
printf(" // BinaryenTypeUnreachable: %d\n", unreachable);
162-
assert(BinaryenTypeArity(unreachable) == 0);
162+
assert(BinaryenTypeArity(unreachable) == 1);
163163
BinaryenTypeExpand(unreachable, &valueType);
164-
assert(valueType == 0xdeadbeef);
164+
assert(valueType == unreachable);
165165

166166
BinaryenType i32 = BinaryenTypeInt32();
167167
printf(" // BinaryenTypeInt32: %d\n", i32);

0 commit comments

Comments
 (0)