diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/gtest/type-builder.cpp | 34 | ||||
-rw-r--r-- | test/lit/passes/type-merging-shared.wast | 74 |
2 files changed, 108 insertions, 0 deletions
diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index 443a7ee66..c0a27b229 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -273,6 +273,40 @@ TEST_F(TypeTest, InvalidFinalSupertype) { EXPECT_EQ(error->index, 1u); } +TEST_F(TypeTest, InvalidSharedSupertype) { + TypeBuilder builder(2); + builder[0] = Struct{}; + builder[1] = Struct{}; + builder[0].setShared(true); + builder[1].setShared(false); + builder[1].subTypeOf(builder[0]); + + auto result = builder.build(); + EXPECT_FALSE(result); + + const auto* error = result.getError(); + ASSERT_TRUE(error); + EXPECT_EQ(error->reason, TypeBuilder::ErrorReason::InvalidSupertype); + EXPECT_EQ(error->index, 1u); +} + +TEST_F(TypeTest, InvalidUnsharedSupertype) { + TypeBuilder builder(2); + builder[0] = Struct{}; + builder[1] = Struct{}; + builder[0].setShared(false); + builder[1].setShared(true); + builder[1].subTypeOf(builder[0]); + + auto result = builder.build(); + EXPECT_FALSE(result); + + const auto* error = result.getError(); + ASSERT_TRUE(error); + EXPECT_EQ(error->reason, TypeBuilder::ErrorReason::InvalidSupertype); + EXPECT_EQ(error->index, 1u); +} + TEST_F(TypeTest, ForwardReferencedChild) { TypeBuilder builder(3); builder.createRecGroup(0, 2); diff --git a/test/lit/passes/type-merging-shared.wast b/test/lit/passes/type-merging-shared.wast new file mode 100644 index 000000000..aefeccc3b --- /dev/null +++ b/test/lit/passes/type-merging-shared.wast @@ -0,0 +1,74 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: foreach %s %t wasm-opt --closed-world --type-merging --remove-unused-types -all -S -o - | filecheck %s + +(module + ;; Shared and non-shared types are not merged. + ;; CHECK: (rec + ;; CHECK-NEXT: (type $C' (shared (func))) + + ;; CHECK: (type $B' (shared (array i8))) + + ;; CHECK: (type $B (array i8)) + + ;; CHECK: (type $A' (shared (struct ))) + + ;; CHECK: (type $A (struct )) + (type $A (struct)) + (type $A' (shared (struct))) + (type $B (array i8)) + (type $B' (shared (array i8))) + ;; CHECK: (type $C (func)) + (type $C (func)) + (type $C' (shared (func))) + + ;; CHECK: (func $foo (type $C) + ;; CHECK-NEXT: (local $a (ref null $A)) + ;; CHECK-NEXT: (local $a' (ref null $A')) + ;; CHECK-NEXT: (local $b (ref null $B)) + ;; CHECK-NEXT: (local $b' (ref null $B')) + ;; CHECK-NEXT: (local $c (ref null $C)) + ;; CHECK-NEXT: (local $c' (ref null $C')) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo + (local $a (ref null $A)) + (local $a' (ref null $A')) + (local $b (ref null $B)) + (local $b' (ref null $B')) + (local $c (ref null $C)) + (local $c' (ref null $C')) + ) +) + +(module + ;; But two shared types can be merged. + ;; CHECK: (rec + ;; CHECK-NEXT: (type $B (shared (array i8))) + + ;; CHECK: (type $A (shared (struct ))) + (type $A (shared (struct))) + (type $A' (shared (struct))) + (type $B (shared (array i8))) + (type $B' (shared (array i8))) + ;; CHECK: (type $C (shared (func))) + (type $C (shared (func))) + (type $C' (shared (func))) + + ;; CHECK: (func $foo (type $C) + ;; CHECK-NEXT: (local $a (ref null $A)) + ;; CHECK-NEXT: (local $a' (ref null $A)) + ;; CHECK-NEXT: (local $b (ref null $B)) + ;; CHECK-NEXT: (local $b' (ref null $B)) + ;; CHECK-NEXT: (local $c (ref null $C)) + ;; CHECK-NEXT: (local $c' (ref null $C)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo + (local $a (ref null $A)) + (local $a' (ref null $A')) + (local $b (ref null $B)) + (local $b' (ref null $B')) + (local $c (ref null $C)) + (local $c' (ref null $C')) + ) +) |