blob: 21c12d4ad76b1f875109804c86809b37059677a6 [file] [log] [blame] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt -all -S -o - | filecheck %s
;; Tests for validation of non-nullable locals.
(module
;; CHECK: (type $0 (func))
;; CHECK: (type $1 (func (param (ref func))))
;; CHECK: (type $2 (func (param funcref) (result i32)))
;; CHECK: (elem declare func $helper)
;; CHECK: (func $no-uses (type $0)
;; CHECK-NEXT: (local $x (ref func))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $no-uses
;; A local with no uses validates.
(local $x (ref func))
)
;; CHECK: (func $func-scope (type $0)
;; CHECK-NEXT: (local $x (ref func))
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (ref.func $helper)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $func-scope
;; a set in the func scope helps a get validate there.
(local $x (ref func))
(local.set $x
(ref.func $helper)
)
(drop
(local.get $x)
)
)
;; CHECK: (func $inner-scope (type $0)
;; CHECK-NEXT: (local $x (ref func))
;; CHECK-NEXT: (block $b
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (ref.func $helper)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $inner-scope
;; a set in an inner scope helps a get validate there.
(local $x (ref func))
(block $b
(local.set $x
(ref.func $helper)
)
(drop
(local.get $x)
)
)
)
;; CHECK: (func $func-to-inner (type $0)
;; CHECK-NEXT: (local $x (ref func))
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (ref.func $helper)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block $b
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $func-to-inner
;; a set in an outer scope helps a get validate.
(local $x (ref func))
(local.set $x
(ref.func $helper)
)
(block $b
(drop
(local.get $x)
)
)
)
;; CHECK: (func $inner-to-func (type $0)
;; CHECK-NEXT: (local $x funcref)
;; CHECK-NEXT: (block $b
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (ref.func $helper)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $inner-to-func
;; a set in an inner scope does *not* help a get validate, but the type is
;; nullable so that's ok.
(local $x (ref null func))
(block $b
(local.set $x
(ref.func $helper)
)
)
(drop
(local.get $x)
)
)
;; CHECK: (func $if-condition (type $0)
;; CHECK-NEXT: (local $x (ref func))
;; CHECK-NEXT: (if
;; CHECK-NEXT: (call $helper2
;; CHECK-NEXT: (local.tee $x
;; CHECK-NEXT: (ref.func $helper)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (else
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-condition
(local $x (ref func))
(if
(call $helper2
;; Tee in the condition is good enough for the arms.
(local.tee $x
(ref.func $helper)
)
)
(then
(drop
(local.get $x)
)
)
(else
(drop
(local.get $x)
)
)
)
)
;; CHECK: (func $get-without-set-but-param (type $1) (param $x (ref func))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get-without-set-but-param
;; As a parameter, this is ok to get without a set.
(param $x (ref func))
(drop
(local.get $x)
)
)
;; CHECK: (func $helper (type $0)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $helper)
;; CHECK: (func $helper2 (type $2) (param $0 funcref) (result i32)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $helper2 (param funcref) (result i32)
(unreachable)
)
)