diff options
-rw-r--r-- | src/wasm/wasm-type.cpp | 9 | ||||
-rw-r--r-- | test/lit/validation/ref-func-multivalue.wast | 19 |
2 files changed, 26 insertions, 2 deletions
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index cebb1b489..e46e0c6ae 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1038,13 +1038,18 @@ FeatureSet Type::getFeatures() const { heapType.getRecGroup().size() > 1 || heapType.getSuperType()) { return FeatureSet::ReferenceTypes | FeatureSet::GC; } + // Otherwise, this is a function reference, which requires reference types + // and possibly also multivalue (if it has multiple returns). // Note: Technically typed function references also require GC, however, // we use these types internally regardless of the presence of GC (in // particular, since during load of the wasm we don't know the features // yet, so we apply the more refined types), so we don't add that in any // case here. - assert(heapType.isSignature()); - return FeatureSet::ReferenceTypes; + FeatureSet feats = FeatureSet::ReferenceTypes; + if (heapType.getSignature().results.isTuple()) { + feats |= FeatureSet::Multivalue; + } + return feats; } TODO_SINGLE_COMPOUND(t); switch (t.getBasic()) { diff --git a/test/lit/validation/ref-func-multivalue.wast b/test/lit/validation/ref-func-multivalue.wast new file mode 100644 index 000000000..f8bb52f46 --- /dev/null +++ b/test/lit/validation/ref-func-multivalue.wast @@ -0,0 +1,19 @@ +;; A local ref of a function type with multiple results requires multivalue. +;; RUN: not wasm-opt %s 2>&1 | filecheck %s + +;; CHECK: all used types should be allowed + +(module + (type $T (func (param i32 i32) (result i32 i32 i32))) + + (func $foo + (local $t (ref null $T)) + ) +) + +;; Still fails with just reference types or multivalue. +;; RUN: not wasm-opt --enable-reference-types %s 2>&1 | filecheck %s +;; RUN: not wasm-opt --enable-multivalue %s 2>&1 | filecheck %s + +;; But it passes with both. +;; RUN: wasm-opt --enable-reference-types --enable-multivalue %s |