summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-05-23 12:44:52 -0700
committerGitHub <noreply@github.com>2022-05-23 19:44:52 +0000
commita78d0e44cbcc72682ab9c45dec76d4b1c52588c9 (patch)
tree8362d3ca459b5c048a7e539eb63e5738f5c18b06 /test
parentfa3ffd0c2697fde7705495b52b139f7939f97925 (diff)
downloadbinaryen-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.wast46
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)
+ )
+ )
+)