diff options
author | Thomas Lively <tlively@google.com> | 2023-10-09 10:12:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-09 10:12:53 -0700 |
commit | 1cd81268627c71f36f45d6ef875dee84a79630f4 (patch) | |
tree | d2f5c9e6e5013d2582035f5a638244d896d88d19 | |
parent | b3775b5e4e150439276ad3d34f1bb564b28e8ef5 (diff) | |
download | binaryen-1cd81268627c71f36f45d6ef875dee84a79630f4.tar.gz binaryen-1cd81268627c71f36f45d6ef875dee84a79630f4.tar.bz2 binaryen-1cd81268627c71f36f45d6ef875dee84a79630f4.zip |
Fix a bug printing and emitting empty, passive element segments (#6002)
Empty, passive element segments were always emitted as having `func` type
because all their elements trivially were RefFunc (because they have no
elements) and because we were incorrectly checking table types if they existed
instead of the element segment's type directly to see if it was non-func.
Fix the bug by checking each element segment's type directly and add a test.
-rw-r--r-- | src/ir/table-utils.cpp | 11 | ||||
-rw-r--r-- | test/lit/empty-elem.wast | 34 | ||||
-rw-r--r-- | test/multi-table.wast.from-wast | 2 | ||||
-rw-r--r-- | test/multi-table.wast.fromBinary | 2 | ||||
-rw-r--r-- | test/multi-table.wast.fromBinary.noDebugInfo | 2 |
5 files changed, 41 insertions, 10 deletions
diff --git a/src/ir/table-utils.cpp b/src/ir/table-utils.cpp index fb9285319..124eb2aa3 100644 --- a/src/ir/table-utils.cpp +++ b/src/ir/table-utils.cpp @@ -72,14 +72,11 @@ bool usesExpressions(ElementSegment* curr, Module* module) { return entry->is<RefFunc>(); }); - // If the table has a specialized (non-MVP) type, then the segment must - // declare a type that is a subtype of that, so it must use the post-MVP form - // of using expressions. - bool hasTableOfSpecializedType = - curr->table.is() && - module->getTable(curr->table)->type != Type(HeapType::func, Nullable); + // If the segment has a specialized (non-MVP) type, then it must use the + // post-MVP form of using expressions. + bool hasSpecializedType = curr->type != Type(HeapType::func, Nullable); - return !allElementsRefFunc || hasTableOfSpecializedType; + return !allElementsRefFunc || hasSpecializedType; } } // namespace wasm::TableUtils diff --git a/test/lit/empty-elem.wast b/test/lit/empty-elem.wast new file mode 100644 index 000000000..0eff01d3c --- /dev/null +++ b/test/lit/empty-elem.wast @@ -0,0 +1,34 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s + +;; Regression test for a bug where empty passive segments were incorrectly +;; printed and emitted as though they had func type even if they had a different +;; type, resulting in invalid modules. + +(module + ;; CHECK: (type $struct (sub (struct ))) + (type $struct (sub (struct))) + + ;; CHECK: (type $array (sub (array (mut (ref null $struct))))) + (type $array (sub (array (mut (ref null $struct))))) + + ;; CHECK: (elem $e (ref null $struct)) + (elem $e (ref null $struct)) + + ;; CHECK: (func $array-init-elem (type $2) + ;; CHECK-NEXT: (array.init_elem $array $e + ;; CHECK-NEXT: (array.new_fixed $array 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array-init-elem + (array.init_elem $array $e + (array.new_fixed $array 0) + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + ) +) diff --git a/test/multi-table.wast.from-wast b/test/multi-table.wast.from-wast index 6ff0120f7..426f474e5 100644 --- a/test/multi-table.wast.from-wast +++ b/test/multi-table.wast.from-wast @@ -11,7 +11,7 @@ (elem $1 (table $t2) (i32.const 0) func $f) (elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g) (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) - (elem $e3-2 (table $t3) (i32.const 2) func $f $g) + (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) (elem $passive-1 func $f $g) (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) diff --git a/test/multi-table.wast.fromBinary b/test/multi-table.wast.fromBinary index 938026af3..c27ec806f 100644 --- a/test/multi-table.wast.fromBinary +++ b/test/multi-table.wast.fromBinary @@ -11,7 +11,7 @@ (elem $1 (table $t2) (i32.const 0) func $f) (elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g) (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) - (elem $e3-2 (table $t3) (i32.const 2) func $f $g) + (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) (elem $passive-1 func $f $g) (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) diff --git a/test/multi-table.wast.fromBinary.noDebugInfo b/test/multi-table.wast.fromBinary.noDebugInfo index ef7f65167..c2a5ef858 100644 --- a/test/multi-table.wast.fromBinary.noDebugInfo +++ b/test/multi-table.wast.fromBinary.noDebugInfo @@ -11,7 +11,7 @@ (elem $1 (table $0) (i32.const 0) func $0) (elem $2 (table $0) (i32.const 1) func $0 $1) (elem $3 (table $1) (global.get $global$1) funcref (ref.func $0) (ref.null nofunc)) - (elem $4 (table $1) (i32.const 2) func $0 $1) + (elem $4 (table $1) (i32.const 2) (ref null $0) (ref.func $0) (ref.func $1)) (elem $5 func $0 $1) (elem $6 funcref (ref.func $0) (ref.func $1) (ref.null nofunc)) (elem $7 (ref null $0) (ref.func $0) (ref.func $1) (ref.null nofunc) (global.get $global$0)) |