From f592d7cfd578f496270c1dd10f434375f11fba54 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Sat, 22 Nov 2025 23:02:40 +0000 Subject: [PATCH] Fix reference tracking in SharedValidator Clear "reference is set" bitset and hasmap in BeginFunctionBody Furtermore support try_tables --- src/shared-validator.cc | 4 ++++ test/regress/regress-2670.txt | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/regress/regress-2670.txt diff --git a/src/shared-validator.cc b/src/shared-validator.cc index cb0aa5a618..93b4a92b6d 100644 --- a/src/shared-validator.cc +++ b/src/shared-validator.cc @@ -540,6 +540,8 @@ Result SharedValidator::BeginFunctionBody(const Location& loc, Index func_index) { expr_loc_ = loc; locals_.clear(); + local_ref_is_set_.clear(); + local_refs_map_.clear(); if (func_index < funcs_.size()) { for (Type type : funcs_[func_index].params) { // TODO: Coalesce parameters of the same type? @@ -1420,6 +1422,7 @@ Result SharedValidator::BeginTryTable(const Location& loc, Type sig_type) { result |= CheckBlockSignature(loc, Opcode::TryTable, sig_type, ¶m_types, &result_types); result |= typechecker_.BeginTryTable(param_types); + SaveLocalRefs(); return result; } @@ -1444,6 +1447,7 @@ Result SharedValidator::EndTryTable(const Location& loc, Type sig_type) { TypeVector param_types, result_types; result |= CheckBlockSignature(loc, Opcode::TryTable, sig_type, ¶m_types, &result_types); + RestoreLocalRefs(result); result |= typechecker_.EndTryTable(param_types, result_types); return result; } diff --git a/test/regress/regress-2670.txt b/test/regress/regress-2670.txt new file mode 100644 index 0000000000..a50eefa6e5 --- /dev/null +++ b/test/regress/regress-2670.txt @@ -0,0 +1,24 @@ +;;; TOOL: run-roundtrip +;;; ARGS: --stdout --fold-exprs --generate-names --enable-function-references --enable-exceptions + +;; This test was failed because the "local is set" bitvector +;; was not cleared in BeginFunctionBody, and the bitvector +;; save/restore operations was missing for try tables + +(module + (func (local (ref func))) + (func + unreachable + try_table + end)) + +(;; STDOUT ;;; +(module + (type $t0 (func)) + (func $f0 (type $t0) + (local $l0 (ref func))) + (func $f1 (type $t0) + (unreachable) + (try_table $T0 + ))) +;;; STDOUT ;;)