summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/gtest/type-builder.cpp34
-rw-r--r--test/lit/passes/type-merging-shared.wast74
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'))
+ )
+)