From ae6c7b4b33e142c890b2b3c118bb544565407ddb Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 16 Oct 2026 03:12:29 -0700 Subject: [PATCH] [Unsubtyping] Handle table.grow SubtypingDiscoverer did not previously note the constraint that TableGrow's `value` operand had to be a subtype of the table's element type. This would cause Unsubtyping to incorrectly remove that subtyping, leading to validation failures. This is included in #9263, but split it out to make the fuzzer happy. --- src/ir/subtype-exprs.h | 5 ++++- test/lit/passes/unsubtyping.wast | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ir/subtype-exprs.h b/src/ir/subtype-exprs.h index 60e4628a7c1..2d4a86f4d68 100644 --- a/src/ir/subtype-exprs.h +++ b/src/ir/subtype-exprs.h @@ -252,7 +252,10 @@ struct SubtypingDiscoverer : public OverriddenVisitor { self()->getModule()->getTable(curr->table)->type); } void visitTableSize(TableSize* curr) {} - void visitTableGrow(TableGrow* curr) {} + void visitTableGrow(TableGrow* curr) { + self()->noteSubtype(curr->value, + self()->getModule()->getTable(curr->table)->type); + } void visitTableFill(TableFill* curr) { self()->noteSubtype(curr->value, self()->getModule()->getTable(curr->table)->type); diff --git a/test/lit/passes/unsubtyping.wast b/test/lit/passes/unsubtyping.wast index 311e0791c9b..2261791d088 100644 --- a/test/lit/passes/unsubtyping.wast +++ b/test/lit/passes/unsubtyping.wast @@ -762,6 +762,37 @@ ) ) +(module + ;; CHECK: (rec + ;; CHECK-NEXT: (type $super (sub (struct))) + (type $super (sub (struct))) + ;; CHECK: (type $sub (sub $super (struct))) + (type $sub (sub $super (struct))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (table $t 1 1 (ref null $super)) + (table $t 1 1 (ref null $super)) + + ;; CHECK: (func $table-grow (type $2) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (table.grow $t + ;; CHECK-NEXT: (struct.new_default $sub) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $table-grow + ;; This requires $sub <: $super. + (drop + (table.grow $t + (struct.new $sub) + (i32.const 0) + ) + ) + ) +) + (module ;; CHECK: (rec ;; CHECK-NEXT: (type $super (sub (struct)))