From 8610aede9790fabf7851f7adf74deeb33498ac3b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 23 Jul 2026 18:04:45 -0700 Subject: [PATCH 1/2] Fuzzer support for br_on_cast_desc_eq When we would generate a br_on_cast or br_on_cast_fail for a type that has a descriptor, sometimes generate a br_on_cast_desc_eq or br_on_cast_desc_eq_fail instead. Fix a validation bug newly found by the fuzzer. --- src/tools/fuzzing/fuzzing.cpp | 14 ++++++++++++-- src/wasm/wasm-validator.cpp | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index f2a8397e6e4..5e2fa6c9a0c 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -5813,8 +5813,18 @@ Expression* TranslateToFuzzReader::makeBrOn(Type type) { WASM_UNREACHABLE("bad br_on op"); } } - return fixFlowingType( - builder.makeBrOn(op, targetName, make(refType), castType)); + auto* ref = make(refType); + if (op == BrOnCast || op == BrOnCastFail) { + auto desc = castType.getHeapType().getDescriptorType(); + if (desc && !oneIn(2)) { + auto descOp = op == BrOnCast ? BrOnCastDescEq : BrOnCastDescEqFail; + auto descType = Type(*desc, Nullable, castType.getExactness()); + auto* descRef = makeTrappingRefUse(descType); + auto* brOn = builder.makeBrOn(descOp, targetName, ref, castType, descRef); + return fixFlowingType(brOn); + } + } + return fixFlowingType(builder.makeBrOn(op, targetName, ref, castType)); } Expression* TranslateToFuzzReader::makeContBind(Type type) { diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 83ad12a81b3..a8f668d6665 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3304,7 +3304,8 @@ void FunctionValidator::visitBrOn(BrOn* curr) { curr->castType.isCastable(), curr, "br_on cannot cast to invalid type"); } - if (curr->ref->type == Type::unreachable) { + if (curr->type == Type::unreachable || + (curr->desc && curr->desc->type == Type::unreachable)) { return; } if (!shouldBeTrue( From f753c76654320b02aa69b1329407072bce213203 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 24 Jul 2026 16:02:52 -0700 Subject: [PATCH 2/2] update tests --- test/lit/help/wasm-as.test | 2 +- test/lit/help/wasm-ctor-eval.test | 2 +- test/lit/help/wasm-dis.test | 2 +- test/lit/help/wasm-emscripten-finalize.test | 2 +- test/lit/help/wasm-merge.test | 2 +- test/lit/help/wasm-metadce.test | 2 +- test/lit/help/wasm-opt.test | 2 +- test/lit/help/wasm-reduce.test | 2 +- test/lit/help/wasm-split.test | 2 +- test/lit/help/wasm2js.test | 2 +- test/lit/passes/dae2-results.wast | 2 +- ...e-to-fuzz_all-features_metrics_noprint.txt | 160 +++++++++--------- 12 files changed, 92 insertions(+), 90 deletions(-) diff --git a/test/lit/help/wasm-as.test b/test/lit/help/wasm-as.test index 2b4902683c5..e169dab6c4a 100644 --- a/test/lit/help/wasm-as.test +++ b/test/lit/help/wasm-as.test @@ -39,7 +39,7 @@ ;; CHECK-NEXT: purposes. ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not emitting -;; CHECK-NEXT: the rest of the names section +;; CHECK-NEXT: the rest of the names section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-ctor-eval.test b/test/lit/help/wasm-ctor-eval.test index 1db625fc55d..717d3c75de0 100644 --- a/test/lit/help/wasm-ctor-eval.test +++ b/test/lit/help/wasm-ctor-eval.test @@ -46,7 +46,7 @@ ;; CHECK-NEXT: purposes. ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not emitting -;; CHECK-NEXT: the rest of the names section +;; CHECK-NEXT: the rest of the names section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-dis.test b/test/lit/help/wasm-dis.test index ab022774484..a2c81677b45 100644 --- a/test/lit/help/wasm-dis.test +++ b/test/lit/help/wasm-dis.test @@ -32,7 +32,7 @@ ;; CHECK-NEXT: purposes. ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not emitting -;; CHECK-NEXT: the rest of the names section +;; CHECK-NEXT: the rest of the names section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-emscripten-finalize.test b/test/lit/help/wasm-emscripten-finalize.test index ac5cab80db4..86860ba7d02 100644 --- a/test/lit/help/wasm-emscripten-finalize.test +++ b/test/lit/help/wasm-emscripten-finalize.test @@ -74,7 +74,7 @@ ;; CHECK-NEXT: purposes. ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not emitting -;; CHECK-NEXT: the rest of the names section +;; CHECK-NEXT: the rest of the names section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-merge.test b/test/lit/help/wasm-merge.test index 3909411ec08..f7fbfdf68f8 100644 --- a/test/lit/help/wasm-merge.test +++ b/test/lit/help/wasm-merge.test @@ -69,7 +69,7 @@ ;; CHECK-NEXT: purposes. ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not emitting -;; CHECK-NEXT: the rest of the names section +;; CHECK-NEXT: the rest of the names section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index f74d904a70b..43234cf67b4 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -703,7 +703,7 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not ;; CHECK-NEXT: emitting the rest of the names -;; CHECK-NEXT: section +;; CHECK-NEXT: section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index e8c9ff02b07..2d712c157c8 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -739,7 +739,7 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not ;; CHECK-NEXT: emitting the rest of the names -;; CHECK-NEXT: section +;; CHECK-NEXT: section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-reduce.test b/test/lit/help/wasm-reduce.test index f881c3d24f3..de35e52d766 100644 --- a/test/lit/help/wasm-reduce.test +++ b/test/lit/help/wasm-reduce.test @@ -122,7 +122,7 @@ ;; CHECK-NEXT: purposes. ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not emitting -;; CHECK-NEXT: the rest of the names section +;; CHECK-NEXT: the rest of the names section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test index e7304d3f618..6a2fb33bc50 100644 --- a/test/lit/help/wasm-split.test +++ b/test/lit/help/wasm-split.test @@ -171,7 +171,7 @@ ;; CHECK-NEXT: purposes. ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not emitting -;; CHECK-NEXT: the rest of the names section +;; CHECK-NEXT: the rest of the names section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 9192c7e4a67..168347c4d9c 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -667,7 +667,7 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --emit-module-names Emit module names, even if not ;; CHECK-NEXT: emitting the rest of the names -;; CHECK-NEXT: section +;; CHECK-NEXT: section. ;; CHECK-NEXT: ;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: diff --git a/test/lit/passes/dae2-results.wast b/test/lit/passes/dae2-results.wast index b98916b4fda..e3f9cd436f0 100644 --- a/test/lit/passes/dae2-results.wast +++ b/test/lit/passes/dae2-results.wast @@ -351,4 +351,4 @@ (func $main (call $caller) ) -) \ No newline at end of file +) diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index d71fc7454a4..f471e76272c 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,91 +1,93 @@ Metrics total - [exports] : 170 - [funcs] : 280 + [exports] : 100 + [funcs] : 190 [globals] : 13 [imports] : 13 [memories] : 1 [memory-data] : 31 - [table-data] : 86 + [table-data] : 50 [tables] : 2 [tags] : 2 - [total] : 74878 - [vars] : 4958 - ArrayCmpxchg : 60 - ArrayCopy : 33 - ArrayFill : 32 - ArrayGet : 367 - ArrayLen : 578 - ArrayNew : 1160 - ArrayNewFixed : 413 - ArrayRMW : 60 - ArraySet : 52 - AtomicCmpxchg : 49 - AtomicFence : 84 - AtomicNotify : 42 - AtomicRMW : 47 - Binary : 3896 - Block : 6899 - BrOn : 272 - Break : 1013 - Call : 1184 - CallIndirect : 213 - CallRef : 221 - Const : 11751 - ContNew : 32 + [total] : 63848 + [vars] : 4419 + ArrayCmpxchg : 50 + ArrayCopy : 22 + ArrayFill : 30 + ArrayGet : 302 + ArrayLen : 473 + ArrayNew : 920 + ArrayNewFixed : 307 + ArrayRMW : 43 + ArraySet : 54 + AtomicCmpxchg : 39 + AtomicFence : 66 + AtomicNotify : 36 + AtomicRMW : 31 + Binary : 3087 + Block : 5531 + BrOn : 267 + Break : 784 + Call : 809 + CallIndirect : 169 + CallRef : 203 + Const : 9748 + ContBind : 1 + ContNew : 25 DataDrop : 13 - Drop : 496 - GlobalGet : 4034 - GlobalSet : 2294 - I31Get : 56 - If : 2582 - Load : 356 - LocalGet : 6322 - LocalSet : 4039 - Loop : 865 - MemoryCopy : 17 - MemoryFill : 17 - MemoryInit : 15 - Nop : 629 - Pop : 320 - RefAs : 4047 - RefCast : 167 - RefEq : 341 - RefFunc : 1204 - RefGetDesc : 54 - RefI31 : 661 - RefIsNull : 74 - RefNull : 5231 - RefTest : 103 - Return : 373 - SIMDExtract : 163 - SIMDLoad : 5 + Drop : 500 + GlobalGet : 3399 + GlobalSet : 1747 + I31Get : 54 + If : 2044 + Load : 274 + LocalGet : 6304 + LocalSet : 3289 + Loop : 681 + MemoryCopy : 19 + MemoryFill : 15 + MemoryInit : 21 + Nop : 586 + Pop : 265 + RefAs : 3780 + RefCast : 132 + RefEq : 296 + RefFunc : 1049 + RefGetDesc : 37 + RefI31 : 638 + RefIsNull : 61 + RefNull : 4652 + RefTest : 63 + Return : 314 + SIMDExtract : 138 + SIMDLoad : 3 SIMDReplace : 3 - SIMDShift : 4 - SIMDShuffle : 4 - SIMDTernary : 2 - Select : 312 - Store : 149 - StringConcat : 2 - StringConst : 447 - StringEncode : 63 - StringEq : 66 - StringMeasure : 55 - StringNew : 5 - StringWTF16Get : 77 - StructCmpxchg : 49 - StructGet : 512 - StructNew : 5149 - StructRMW : 61 + SIMDShift : 1 + SIMDShuffle : 1 + SIMDTernary : 3 + Select : 276 + Store : 128 + StringConcat : 1 + StringConst : 345 + StringEncode : 56 + StringEq : 53 + StringMeasure : 60 + StringNew : 3 + StringSliceWTF : 1 + StringWTF16Get : 55 + StructCmpxchg : 58 + StructGet : 477 + StructNew : 5073 + StructRMW : 42 StructSet : 67 - Switch : 10 - TableGet : 2 - TableSet : 76 - Throw : 74 + Switch : 8 + TableGet : 1 + TableSet : 64 + Throw : 46 ThrowRef : 5 - Try : 421 - TryTable : 482 - TupleExtract : 238 - TupleMake : 296 - Unary : 2139 - Unreachable : 1172 + Try : 340 + TryTable : 362 + TupleExtract : 160 + TupleMake : 179 + Unary : 1715 + Unreachable : 894