diff options
author | Alon Zakai <azakai@google.com> | 2022-04-21 17:04:01 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-21 17:04:01 -0700 |
commit | 6000629ae7cc2962483cd0d7ae4a770c8f2a34a0 (patch) | |
tree | 0b4a51277e677c47533590f4fcec6afe72df9c77 | |
parent | 50d596b3287f19e4ff2f1e1d4a9629968695da73 (diff) | |
download | binaryen-6000629ae7cc2962483cd0d7ae4a770c8f2a34a0.tar.gz binaryen-6000629ae7cc2962483cd0d7ae4a770c8f2a34a0.tar.bz2 binaryen-6000629ae7cc2962483cd0d7ae4a770c8f2a34a0.zip |
[NominalFuzzing] GTO: trap on null ref in removed struct.set (#4607)
When a field has no reads, we remove all its writes, but we did this:
(struct.set $foo A B)
=>
(drop A) (drop B)
We also need to trap if A, the reference, is null, which this PR
fixes,
(struct.set $foo A B)
=>
(drop (ref.as_non_null A)) (drop B)
-rw-r--r-- | src/passes/GlobalTypeOptimization.cpp | 8 | ||||
-rw-r--r-- | test/lit/passes/gto-removals.wast | 12 |
2 files changed, 14 insertions, 6 deletions
diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp index 7e1ebf04e..53c76ca6f 100644 --- a/src/passes/GlobalTypeOptimization.cpp +++ b/src/passes/GlobalTypeOptimization.cpp @@ -391,10 +391,12 @@ struct GlobalTypeOptimization : public Pass { // Map to the new index. curr->index = newIndex; } else { - // This field was removed, so just emit drops of our children. + // This field was removed, so just emit drops of our children (plus a + // trap if the input is null). Builder builder(*getModule()); - replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref), - builder.makeDrop(curr->value))); + replaceCurrent(builder.makeSequence( + builder.makeDrop(builder.makeRefAs(RefAsNonNull, curr->ref)), + builder.makeDrop(curr->value))); } } diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index 92e98ee2a..1d80b24ee 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -29,7 +29,9 @@ ;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.null func) @@ -140,7 +142,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) @@ -162,7 +166,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 2) |