From 4c85e8497f67524cfd1869c2bfb612fbc387ddba Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 15 May 2026 15:50:08 -0700 Subject: [PATCH 1/2] Fix validation error in wasm-reduce When removing functions, wasm-reduce replaces calls to those functions using `builder.replaceWithIdenticalType`. That method can modify the input expression in-place to have a different types (e.g. replacing a reference with a null), so when the previous code read `curr->type` to set the type of the replacement block, it was possible to get a more refined type, leading to validation failures. Fix the bug by explicitly using the original type. --- src/tools/wasm-reduce/wasm-reduce.cpp | 3 ++- .../wasm-reduce/reduce-validation-error.wast | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/lit/wasm-reduce/reduce-validation-error.wast diff --git a/src/tools/wasm-reduce/wasm-reduce.cpp b/src/tools/wasm-reduce/wasm-reduce.cpp index bba5cda3cb1..04676109acf 100644 --- a/src/tools/wasm-reduce/wasm-reduce.cpp +++ b/src/tools/wasm-reduce/wasm-reduce.cpp @@ -1102,6 +1102,7 @@ struct Reducer auto* block = ChildLocalizer(curr, getFunction(), *getModule(), getPassOptions()) .getChildrenReplacement(); + auto originalType = curr->type; auto* replacement = builder.replaceWithIdenticalType(curr); // We may have failed to come up with a replacement (e.g. for // non-nullable references), so manually add an `unreachable` in that @@ -1110,7 +1111,7 @@ struct Reducer replacement = builder.makeUnreachable(); } block->list.push_back(replacement); - block->type = curr->type; + block->type = originalType; replaceCurrent(block); } void visitRefFunc(RefFunc* curr) { diff --git a/test/lit/wasm-reduce/reduce-validation-error.wast b/test/lit/wasm-reduce/reduce-validation-error.wast new file mode 100644 index 00000000000..a8e7c6c5de7 --- /dev/null +++ b/test/lit/wasm-reduce/reduce-validation-error.wast @@ -0,0 +1,19 @@ +;; This is a regression test for a crash in wasm-reduce where in-place mutation +;; of a Call node during replaceWithIdenticalType caused the replacement block +;; type to be set incorrectly to nullref instead of the original type, leading +;; to a validation error. + +;; RUN: wasm-reduce %s -t %t.t.wast -w %t.w.wast \ +;; RUN: --command=' wasm-opt %t.t.wast -all --fuzz-exec' + +(module + (func $to_remove (result anyref) + (ref.null none) + ) + + (func $main (export "main") (result anyref) + ;; This will be replaced with a nullref. This should not cause validation + ;; failures and cause wasm-reduce to crash. + (call $to_remove) + ) +) From b1a52faf381d0e16b0d0261591a52adff4011a7a Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 15 May 2026 16:31:39 -0700 Subject: [PATCH 2/2] remove space --- test/lit/wasm-reduce/reduce-validation-error.wast | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lit/wasm-reduce/reduce-validation-error.wast b/test/lit/wasm-reduce/reduce-validation-error.wast index a8e7c6c5de7..74ef8f13864 100644 --- a/test/lit/wasm-reduce/reduce-validation-error.wast +++ b/test/lit/wasm-reduce/reduce-validation-error.wast @@ -4,7 +4,7 @@ ;; to a validation error. ;; RUN: wasm-reduce %s -t %t.t.wast -w %t.w.wast \ -;; RUN: --command=' wasm-opt %t.t.wast -all --fuzz-exec' +;; RUN: --command='wasm-opt %t.t.wast -all --fuzz-exec' (module (func $to_remove (result anyref)