Skip to content

Unsubtyping fuzz bug #6565

@kripken

Description

@kripken
$ wasm-opt x.wat -all --type-ssa -O2 --unsubtyping --roundtrip
[wasm-validator error in module] struct.new operand 0 must have proper type, on 
(struct.new $84
 (global.get $global$4)
)
Fatal: error after opts

After the unsubtyping pass the IR passes validation but is incorrect in some subtle way, which causes errors in roundtripping and other operations (e.g. --precompute instead of --roundtrip will also error, on some internal assertion).

I'd guess this is some subtle bug of Unsubtyping and/or the Type canonicalization logic. @tlively I think you know that code best, can you take a look?

(module
 (rec
  (type $0 (struct (field (ref $3))))
  (type $1 (sub (struct (field (ref null $52)) (field (mut i8)))))
  (type $2 (sub final $1 (struct (field (ref $52)) (field (mut i8)) (field (ref $0)))))
  (type $3 (struct (field (mut i32)) (field i32) (field (ref null $74))))
  (type $4 (sub (struct )))
  (type $5 (sub $4 (struct (field (ref $4)) (field (ref $85)))))
  (type $6 (sub $5 (struct (field (ref $4)) (field (ref $85)) (field (ref $54)) (field (mut i32)) (field (ref $54)))))
  (type $7 (sub final $6 (struct (field (ref $4)) (field (ref $85)) (field (ref $54)) (field (mut i32)) (field (ref $54)) (field (mut i32)))))
  (type $8 (func (param (ref $6)) (result (ref $55))))
  (type $9 (func (param (ref $29)) (result (ref $18))))
  (type $10 (sub $5 (struct (field (ref $4)) (field (ref $85)) (field (mut (ref $83))) (field (mut i32)))))
  (type $11 (sub final $10 (struct (field (ref $4)) (field (ref $85)) (field (mut (ref $83))) (field (mut i32)) (field (mut i32)))))
  (type $12 (func (result (ref $56))))
  (type $13 (func (param (ref $73))))
  (type $14 (func (param (ref $73)) (result (ref null $74))))
  (type $15 (func (param (ref null $82) (ref null $82) i32 i32 i32)))
  (type $16 (func (param (ref $38) (ref null $92)) (result (ref null $92))))
  (type $17 (func (param (ref $70) (ref null $18))))
  (type $18 (sub (struct (field (ref $93)) (field (ref $79)) (field (mut i32)))))
  (type $19 (sub final $18 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field i32))))
  (type $20 (func (param i32) (result (ref null $19))))
  (type $21 (func (param i32) (result (ref $92))))
  (type $22 (func (param (ref $5)) (result (ref $18))))
  (type $23 (func (param (ref $5)) (result i32)))
  (type $24 (func (param (ref $5)) (result (ref null $18))))
  (type $25 (func (param (ref $5) (ref null $18)) (result i32)))
  (type $26 (func (param (ref $5))))
  (type $27 (func (param (ref $38)) (result (ref null $92))))
  (type $28 (struct (field (ref null $92))))
  (type $29 (sub $4 (struct (field (ref $84)))))
  (type $30 (sub final $29 (struct (field (ref $84)) (field (ref $38)))))
  (type $31 (func (param (ref $38))))
  (type $32 (sub final $18 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field f64))))
  (type $33 (sub final $18 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)))))
  (type $34 (func (param (ref null $73) i32) (result (ref $66))))
  (type $35 (func (param (ref $92) (ref $83))))
  (type $36 (func (param externref) (result (ref null $56))))
  (type $37 (func (param (ref $56)) (result (ref $64))))
  (type $38 (sub (struct (field (ref $4)) (field (ref $78)) (field (mut (ref null $30))) (field (mut i32)) (field (mut i32)) (field (mut (ref $83))) (field (mut i32)))))
  (type $39 (sub final $38 (struct (field (ref $4)) (field (ref $78)) (field (mut (ref null $30))) (field (mut i32)) (field (mut i32)) (field (mut (ref $83))) (field (mut i32)) (field (ref $41)))))
  (type $40 (sub $18 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field i32) (field (ref null $92)) (field (mut (ref null $40))) (field (mut (ref null $92))))))
  (type $41 (sub final $40 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field i32) (field (ref null $92)) (field (mut (ref null $40))) (field (mut (ref null $92))) (field (mut (ref null $41))) (field (mut (ref null $41))))))
  (type $42 (sub final $18 (struct (field (ref $93)) (field (ref $80)) (field (mut i32)) (field (ref $39)) (field (mut (ref null $41))) (field (mut (ref null $41))))))
  (type $43 (sub final $18 (struct (field (ref $93)) (field (ref $80)) (field (mut i32)) (field (ref $38)) (field (mut (ref null $40))) (field (mut (ref null $40))) (field (mut i32)))))
  (type $44 (func (param f64) (result (ref null $92))))
  (type $45 (func (param i32) (result (ref null $92))))
  (type $46 (func (param (ref $76)) (result (ref null $92))))
  (type $47 (func (param (ref $92) (ref $92)) (result (ref $92))))
  (type $48 (func (param (ref $70) (ref $92) i32 i32)))
  (type $49 (func (param (ref $70) (ref null $92))))
  (type $50 (func (param (ref $70))))
  (type $51 (func (param (ref $70) i32)))
  (type $52 (sub final $1 (struct (field nullref) (field (mut i8)) (field (ref $3)))))
  (type $53 (func (param (ref $1))))
  (type $54 (struct (field (mut (ref null $54))) (field (mut (ref null $54))) (field (mut (ref null $92)))))
  (type $55 (sub final $18 (struct (field (ref $93)) (field (ref $80)) (field (mut i32)) (field (ref $6)) (field (mut i32)) (field (mut (ref null $54))) (field (mut (ref null $54))))))
  (type $56 (sub $18 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field (mut (ref null $64))) (field (mut (ref null $92))))))
  (type $57 (sub $56 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field (mut (ref null $64))) (field (mut (ref null $92))))))
  (type $58 (sub final $57 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field (mut (ref null $64))) (field (mut (ref null $92))))))
  (type $59 (func (param (ref $18))))
  (type $60 (func (param (ref $18)) (result (ref null $18))))
  (type $61 (sub final $18 (struct (field (ref $93)) (field (ref $80)) (field (mut i32)) (field (ref $10)) (field (mut i32)) (field (mut i32)))))
  (type $62 (func (param (ref $56) (ref $64))))
  (type $63 (func (result i64)))
  (type $64 (sub final $18 (struct (field (ref $93)) (field (ref $79)) (field (mut i32)) (field externref))))
  (type $65 (func (param (ref null $90) i32 (ref null $90) i32 i32)))
  (type $66 (struct (field (mut f64)) (field (ref $67))))
  (type $67 (struct (field (ref $77))))
  (type $68 (sub final $18 (struct (field (ref $93)) (field (ref $79)) (field (mut i32)) (field (mut (ref null $70))) (field (mut (ref null $92))))))
  (type $69 (func (param (ref $18)) (result (ref $76))))
  (type $70 (struct (field (mut i32)) (field (mut (ref null $90)))))
  (type $71 (func (param (ref $18)) (result (ref null $92))))
  (type $72 (func (param (ref $18)) (result i32)))
  (type $73 (struct (field (mut (ref null $74)))))
  (type $74 (struct (field (ref $82))))
  (type $75 (sub final $18 (struct (field (ref $93)) (field (ref $80)) (field (mut i32)))))
  (type $76 (struct (field (mut (ref null $92)))))
  (type $77 (array (mut f64)))
  (type $78 (struct (field (ref $88))))
  (type $79 (sub (struct (field structref))))
  (type $80 (sub final $79 (struct (field (ref $81)))))
  (type $81 (struct (field (ref $72)) (field (ref $60)) (field (ref $59))))
  (type $82 (array (mut i32)))
  (type $83 (struct (field (ref $89))))
  (type $84 (struct (field (ref $4))))
  (type $85 (struct (field (ref $87)) (field (ref $86))))
  (type $86 (struct (field (ref $24)) (field (ref $22)) (field (ref $24))))
  (type $87 (struct (field (ref $25)) (field (ref $23))))
  (type $88 (struct (field (ref $27))))
  (type $89 (array (mut (ref null $18))))
  (type $90 (struct (field (ref $91))))
  (type $91 (array (mut i16)))
  (type $92 (sub final $18 (struct (field (ref $93)) (field (ref $94)) (field (mut i32)) (field (mut i32)) (field (ref string)))))
  (type $93 (struct (field (ref $69)) (field (ref $72)) (field (ref $71))))
  (type $94 (sub final $79 (struct (field (ref $4)))))
 )
 (rec
  (type $38_1 (sub $38 (struct (field (ref $4)) (field (ref $78)) (field (mut (ref null $30))) (field (mut i32)) (field (mut i32)) (field (mut (ref $83))) (field (mut i32)))))
  (type $4_2 (sub $4 (struct )))
  (type $4_3 (sub $4 (struct )))
  (type $4_4 (sub $4 (struct )))
 )
 (type $95 (func))
 (global $global$0 (ref $88) (struct.new $88
  (ref.func $2)
 ))
 (global $global$1 (ref $4_2) (struct.new_default $4_2))
 (global $global$3 (ref $83) (struct.new $83
  (array.new_default $89
   (i32.const 0)
  )
 ))
 (global $global$4 (ref $4_3) (struct.new_default $4_3))
 (global $global$5 (ref $78) (struct.new $78
  (struct.new $88
   (ref.func $2)
  )
 ))
 (global $global$6 (ref $4_4) (struct.new_default $4_4))
 (global $global$7 (ref $78) (struct.new $78
  (struct.new $88
   (ref.func $2)
  )
 ))
 (global $global$8 (ref $29) (struct.new $29
  (struct.new $84
   (global.get $global$4)
  )
 ))
 (export "prepareForRunOnce" (func $0))
 (func $0 (type $95) (; has Stack IR ;)
  (local $0 (ref null $41))
  (call $1
   (struct.new $38_1
    (global.get $global$1)
    (global.get $global$7)
    (ref.null none)
    (i32.const 0)
    (i32.const 0)
    (global.get $global$3)
    (i32.const 0)
   )
  )
  (call $1
   (struct.new $39
    (global.get $global$6)
    (global.get $global$5)
    (ref.null none)
    (i32.const 0)
    (i32.const 0)
    (global.get $global$3)
    (i32.const 0)
    (ref.as_non_null
     (local.get $0)
    )
   )
  )
  (unreachable)
 )
 (func $1 (type $31) (; has Stack IR ;) (param $0 (ref $38))
  (if
   (ref.eq
    (struct.get $84 0
     (struct.get $29 0
      (if (result (ref $29))
       (ref.eq
        (struct.get $78 0
         (struct.get $38 1
          (local.get $0)
         )
        )
        (global.get $global$0)
       )
       (then
        (global.get $global$8)
       )
       (else
        (unreachable)
       )
      )
     )
    )
    (global.get $global$4)
   )
   (then
    (unreachable)
   )
  )
  (unreachable)
 )
 (func $2 (type $27) (; has Stack IR ;) (param $0 (ref $38)) (result (ref null $92))
  (unreachable)
 )
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions