diff options
author | Alon Zakai <azakai@google.com> | 2022-05-23 12:44:52 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-23 19:44:52 +0000 |
commit | a78d0e44cbcc72682ab9c45dec76d4b1c52588c9 (patch) | |
tree | 8362d3ca459b5c048a7e539eb63e5738f5c18b06 /test | |
parent | fa3ffd0c2697fde7705495b52b139f7939f97925 (diff) | |
download | binaryen-a78d0e44cbcc72682ab9c45dec76d4b1c52588c9.tar.gz binaryen-a78d0e44cbcc72682ab9c45dec76d4b1c52588c9.tar.bz2 binaryen-a78d0e44cbcc72682ab9c45dec76d4b1c52588c9.zip |
[Nominal Fuzzing] Fix SignatureRefining by updating types fully at once (#4665)
Optionally avoid updating types in TypeUpdating::updateParamTypes(). That update
is incomplete if the function signature is also changing, which is the case in
SignatureRefining (but not DeadArgumentElimination). "Incomplete" means that
we updated the local.get type, but the function signature does not match yet. That
incomplete state can hit an internal error in GlobalTypeRewriter::updateSignatures
where it updates types. To avoid that, do the entire full update only there (in
GlobalTypeRewriter::updateSignatures).
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/signature-refining.wast | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast index 19558d997..8e5d3b75e 100644 --- a/test/lit/passes/signature-refining.wast +++ b/test/lit/passes/signature-refining.wast @@ -674,3 +674,49 @@ (nop) ) ) + +(module + ;; CHECK: (type $ref|${}|_i32_=>_none (func_subtype (param (ref ${}) i32) func)) + + ;; CHECK: (type ${} (struct_subtype data)) + (type ${} (struct_subtype data)) + + ;; CHECK: (func $foo (type $ref|${}|_i32_=>_none) (param $ref (ref ${})) (param $i32 i32) + ;; CHECK-NEXT: (local $2 eqref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $ref) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $foo + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (ref.null eq) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $foo (param $ref eqref) (param $i32 i32) + (call $foo + ;; The only reference to the ${} type is in this block signature. Even + ;; this will go away in the internal ReFinalize (which makes the block + ;; type unreachable). + (block (result (ref ${})) + (unreachable) + ) + (i32.const 0) + ) + ;; Write something of type eqref into $ref. When we refine the type of the + ;; parameter from eqref to ${} we must do something here, as we can no + ;; longer just write this (ref.null eq) into a parameter of the more + ;; refined type. While doing so, we must not be confused by the fact that + ;; the only mention of ${} in the original module gets removed during our + ;; processing, as mentioned in the earlier comment. This is a regression + ;; test for a crash because of that. + (local.set $ref + (ref.null eq) + ) + ) +) |