Skip to content

Commit 566e2c1

Browse files
authored
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.
1 parent 83f6232 commit 566e2c1

4 files changed

Lines changed: 139 additions & 18 deletions

File tree

src/passes/ReReloop.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,18 @@ struct ReReloop final : public Pass {
345345
auto temp = builder->addVar(function, i32);
346346
CFG::RelooperBuilder builder(*module, temp);
347347
function->body = relooper.Render(builder);
348+
// if the function has a result, and the relooper emitted
349+
// something that seems like it flows out without a value
350+
// (but that path is never reached; it just has a br to it
351+
// because of the relooper's boilerplate switch-handling
352+
// code, for example, which could be optimized out later
353+
// but isn't yet), then make sure it has a proper type
354+
if (function->result != none && function->body->type == none) {
355+
function->body = builder.makeSequence(
356+
function->body,
357+
builder.makeUnreachable()
358+
);
359+
}
348360
}
349361
// TODO: should this be in the relooper itself?
350362
ReFinalize().walk(function->body);

test/passes/flatten_rereloop.txt

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,85 @@
4343
)
4444
)
4545
)
46+
(module
47+
(type $0 (func (result i32)))
48+
(memory $0 0)
49+
(func $0 (; 0 ;) (type $0) (result i32)
50+
(local $0 i32)
51+
(local $1 i32)
52+
(local $2 i32)
53+
(block
54+
(block
55+
)
56+
(block $switch$1$leave
57+
(block $switch$1$default
58+
(block $switch$1$case$5
59+
(block $switch$1$case$4
60+
(br_table $switch$1$case$5 $switch$1$case$4 $switch$1$default
61+
(i32.const 0)
62+
)
63+
)
64+
(block
65+
(block
66+
(block
67+
(nop)
68+
(unreachable)
69+
)
70+
)
71+
)
72+
)
73+
(block
74+
(block
75+
(block
76+
(nop)
77+
(unreachable)
78+
)
79+
)
80+
)
81+
)
82+
(block
83+
(block
84+
(block
85+
(nop)
86+
)
87+
(block $switch$6$leave
88+
(block $switch$6$default
89+
(block $switch$6$case$3
90+
(br_table $switch$6$case$3 $switch$6$default
91+
(i32.const 1)
92+
)
93+
)
94+
(block
95+
(block
96+
(block
97+
(nop)
98+
(unreachable)
99+
)
100+
)
101+
)
102+
)
103+
(block
104+
(block
105+
(block
106+
(nop)
107+
(set_local $0
108+
(i32.const 2)
109+
)
110+
(set_local $1
111+
(get_local $0)
112+
)
113+
(return
114+
(get_local $1)
115+
)
116+
)
117+
)
118+
)
119+
)
120+
)
121+
)
122+
(br $switch$1$leave)
123+
)
124+
)
125+
(unreachable)
126+
)
127+
)

test/passes/flatten_rereloop.wast

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,28 @@
99
(f64.const -nan:0xfffffd63e4e5a)
1010
)
1111
)
12+
(module
13+
(func $0 (result i32)
14+
(block $label$8
15+
(block $label$9
16+
(block $label$16
17+
(block $label$18
18+
(block $label$19
19+
(br_table $label$18 $label$16 $label$19
20+
(i32.const 0)
21+
)
22+
)
23+
(br_table $label$9 $label$8
24+
(i32.const 1)
25+
)
26+
)
27+
(unreachable)
28+
)
29+
(unreachable)
30+
)
31+
(unreachable)
32+
)
33+
(i32.const 2)
34+
)
35+
)
1236

test/passes/rereloop.txt

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -713,20 +713,31 @@
713713
(func $switcher-to-nowhere (; 13 ;) (type $2) (param $0 i32) (result i32)
714714
(local $1 i32)
715715
(block
716-
)
717-
(block $switch$1$leave
718-
(block $switch$1$default
719-
(block $switch$1$case$3
720-
(block $switch$1$case$4
721-
(br_table $switch$1$case$4 $switch$1$case$3 $switch$1$default
722-
(get_local $0)
716+
(block
717+
)
718+
(block $switch$1$leave
719+
(block $switch$1$default
720+
(block $switch$1$case$3
721+
(block $switch$1$case$4
722+
(br_table $switch$1$case$4 $switch$1$case$3 $switch$1$default
723+
(get_local $0)
724+
)
725+
)
726+
(block
727+
(block
728+
(block
729+
(return
730+
(i32.const 1)
731+
)
732+
)
733+
)
723734
)
724735
)
725736
(block
726737
(block
727738
(block
728739
(return
729-
(i32.const 1)
740+
(i32.const 2)
730741
)
731742
)
732743
)
@@ -736,22 +747,14 @@
736747
(block
737748
(block
738749
(return
739-
(i32.const 2)
750+
(i32.const 3)
740751
)
741752
)
742753
)
743754
)
744755
)
745-
(block
746-
(block
747-
(block
748-
(return
749-
(i32.const 3)
750-
)
751-
)
752-
)
753-
)
754756
)
757+
(unreachable)
755758
)
756759
)
757760
(module

0 commit comments

Comments
 (0)