https://github.com/ppenzin updated 
https://github.com/llvm/llvm-project/pull/178720

>From a81b640f7a648b3d82409ba38eea09271714d8f1 Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <[email protected]>
Date: Thu, 29 Jan 2026 00:54:20 -0800
Subject: [PATCH 1/3] Change `QualType::isWebAssemblyFuncrefType` to accept
 types attributed with `WebAssemblyFuncref`

---
 clang/lib/AST/Type.cpp                          |  3 ++-
 clang/test/CodeGen/WebAssembly/builtins-table.c | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 53082bcf78f6a..8cbe49a23c13d 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2947,7 +2947,8 @@ bool QualType::isWebAssemblyExternrefType() const {
 
 bool QualType::isWebAssemblyFuncrefType() const {
   return getTypePtr()->isFunctionPointerType() &&
-         getAddressSpace() == LangAS::wasm_funcref;
+         (getAddressSpace() == LangAS::wasm_funcref ||
+          getTypePtr()->hasAttr(attr::WebAssemblyFuncref));
 }
 
 QualType::PrimitiveDefaultInitializeKind
diff --git a/clang/test/CodeGen/WebAssembly/builtins-table.c 
b/clang/test/CodeGen/WebAssembly/builtins-table.c
index 74bb2442fe552..4069da2c4c225 100644
--- a/clang/test/CodeGen/WebAssembly/builtins-table.c
+++ b/clang/test/CodeGen/WebAssembly/builtins-table.c
@@ -65,3 +65,20 @@ static __externref_t other_table[0];
 void test_table_copy(int dst_idx, int src_idx, int nelem) {
   __builtin_wasm_table_copy(table, other_table, dst_idx, src_idx, nelem);
 }
+
+
+typedef void (*__funcref funcref_t)();
+static funcref_t funcref_table[0];
+
+// CHECK-LABEL: define {{[^@]+}}@test_funcref_table
+// CHECK-SAME: (ptr addrspace(20) noundef [[FUNCREF:%.*]], i32 noundef 
[[INDEX:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    call void @llvm.wasm.table.set.funcref(ptr addrspace(1) 
@funcref_table, i32 [[INDEX]], ptr addrspace(20) [[FUNCREF]])
+// CHECK-NEXT:    [[TMP0:%.*]] = call ptr addrspace(20) 
@llvm.wasm.table.get.funcref(ptr addrspace(1) @funcref_table, i32 [[INDEX]])
+// CHECK-NEXT:    ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t test_funcref_table(funcref_t funcref, int index) {
+  __builtin_wasm_table_set(funcref_table, index, funcref);
+
+  return __builtin_wasm_table_get(funcref_table, index);
+}

>From 9bb0dfce3e091b7ba74777e05352787f112b8065 Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <[email protected]>
Date: Thu, 29 Jan 2026 15:01:28 -0800
Subject: [PATCH 2/3] Alternative approach

---
 clang/lib/AST/Type.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 8cbe49a23c13d..dcdbb62f9d62b 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2947,8 +2947,8 @@ bool QualType::isWebAssemblyExternrefType() const {
 
 bool QualType::isWebAssemblyFuncrefType() const {
   return getTypePtr()->isFunctionPointerType() &&
-         (getAddressSpace() == LangAS::wasm_funcref ||
-          getTypePtr()->hasAttr(attr::WebAssemblyFuncref));
+         (getTypePtr()->getPointeeType().getAddressSpace() ==
+          LangAS::wasm_funcref);
 }
 
 QualType::PrimitiveDefaultInitializeKind

>From c93e4544dfc7a9d0dcb3bacec26a158bc2370b6f Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <[email protected]>
Date: Fri, 30 Jan 2026 12:27:35 -0800
Subject: [PATCH 3/3] Improve tests. Fix `__builtin_wasm_table_grow` for
 funcref.

---
 .../CodeGen/TargetBuiltins/WebAssembly.cpp    |  4 +-
 ...ins-table.c => builtins-table-externref.c} | 17 -----
 .../WebAssembly/builtins-table-funcref.c      | 69 +++++++++++++++++++
 clang/test/Sema/wasm-funcref-table.c          | 18 +++++
 4 files changed, 89 insertions(+), 19 deletions(-)
 rename clang/test/CodeGen/WebAssembly/{builtins-table.c => 
builtins-table-externref.c} (80%)
 create mode 100644 clang/test/CodeGen/WebAssembly/builtins-table-funcref.c
 create mode 100644 clang/test/Sema/wasm-funcref-table.c

diff --git a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp 
b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp
index 1a1889a4139d3..edaba6e5998fc 100644
--- a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp
@@ -633,8 +633,8 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned 
BuiltinID,
     Function *Callee;
     if (E->getArg(1)->getType().isWebAssemblyExternrefType())
       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_grow_externref);
-    else if (E->getArg(2)->getType().isWebAssemblyFuncrefType())
-      Callee = CGM.getIntrinsic(Intrinsic::wasm_table_fill_funcref);
+    else if (E->getArg(1)->getType().isWebAssemblyFuncrefType())
+      Callee = CGM.getIntrinsic(Intrinsic::wasm_table_grow_funcref);
     else
       llvm_unreachable(
           "Unexpected reference type for __builtin_wasm_table_grow");
diff --git a/clang/test/CodeGen/WebAssembly/builtins-table.c 
b/clang/test/CodeGen/WebAssembly/builtins-table-externref.c
similarity index 80%
rename from clang/test/CodeGen/WebAssembly/builtins-table.c
rename to clang/test/CodeGen/WebAssembly/builtins-table-externref.c
index 4069da2c4c225..74bb2442fe552 100644
--- a/clang/test/CodeGen/WebAssembly/builtins-table.c
+++ b/clang/test/CodeGen/WebAssembly/builtins-table-externref.c
@@ -65,20 +65,3 @@ static __externref_t other_table[0];
 void test_table_copy(int dst_idx, int src_idx, int nelem) {
   __builtin_wasm_table_copy(table, other_table, dst_idx, src_idx, nelem);
 }
-
-
-typedef void (*__funcref funcref_t)();
-static funcref_t funcref_table[0];
-
-// CHECK-LABEL: define {{[^@]+}}@test_funcref_table
-// CHECK-SAME: (ptr addrspace(20) noundef [[FUNCREF:%.*]], i32 noundef 
[[INDEX:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @llvm.wasm.table.set.funcref(ptr addrspace(1) 
@funcref_table, i32 [[INDEX]], ptr addrspace(20) [[FUNCREF]])
-// CHECK-NEXT:    [[TMP0:%.*]] = call ptr addrspace(20) 
@llvm.wasm.table.get.funcref(ptr addrspace(1) @funcref_table, i32 [[INDEX]])
-// CHECK-NEXT:    ret ptr addrspace(20) [[TMP0]]
-//
-funcref_t test_funcref_table(funcref_t funcref, int index) {
-  __builtin_wasm_table_set(funcref_table, index, funcref);
-
-  return __builtin_wasm_table_get(funcref_table, index);
-}
diff --git a/clang/test/CodeGen/WebAssembly/builtins-table-funcref.c 
b/clang/test/CodeGen/WebAssembly/builtins-table-funcref.c
new file mode 100644
index 0000000000000..b4f729669a795
--- /dev/null
+++ b/clang/test/CodeGen/WebAssembly/builtins-table-funcref.c
@@ -0,0 +1,69 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types 
-disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s
+// REQUIRES: webassembly-registered-target
+
+typedef void (*__funcref funcref_t)();
+static funcref_t table[0];
+
+// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_get
+// CHECK-SAME: (i32 noundef [[INDEX:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call ptr addrspace(20) 
@llvm.wasm.table.get.funcref(ptr addrspace(1) @table, i32 [[INDEX]])
+// CHECK-NEXT:    ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t test_builtin_wasm_table_get(int index) {
+  return __builtin_wasm_table_get(table, index);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_set
+// CHECK-SAME: (i32 noundef [[INDEX:%.*]], ptr addrspace(20) noundef 
[[REF:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    call void @llvm.wasm.table.set.funcref(ptr addrspace(1) 
@table, i32 [[INDEX]], ptr addrspace(20) [[REF]])
+// CHECK-NEXT:    ret void
+//
+void test_builtin_wasm_table_set(int index, funcref_t ref) {
+  return __builtin_wasm_table_set(table, index, ref);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_size
+// CHECK-SAME: () #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.wasm.table.size(ptr 
addrspace(1) @table)
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int test_builtin_wasm_table_size() {
+  return __builtin_wasm_table_size(table);
+}
+
+
+// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_grow
+// CHECK-SAME: (ptr addrspace(20) noundef [[REF:%.*]], i32 noundef 
[[NELEM:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.wasm.table.grow.funcref(ptr 
addrspace(1) @table, ptr addrspace(20) [[REF]], i32 [[NELEM]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int test_builtin_wasm_table_grow(funcref_t ref, int nelem) {
+  return __builtin_wasm_table_grow(table, ref, nelem);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_fill
+// CHECK-SAME: (i32 noundef [[INDEX:%.*]], ptr addrspace(20) noundef 
[[REF:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    call void @llvm.wasm.table.fill.funcref(ptr addrspace(1) 
@table, i32 [[INDEX]], ptr addrspace(20) [[REF]], i32 [[NELEM]])
+// CHECK-NEXT:    ret void
+//
+void test_builtin_wasm_table_fill(int index, funcref_t ref, int nelem) {
+  __builtin_wasm_table_fill(table, index, ref, nelem);
+}
+
+static funcref_t other_table[0];
+
+// CHECK-LABEL: define {{[^@]+}}@test_table_copy
+// CHECK-SAME: (i32 noundef [[DST_IDX:%.*]], i32 noundef [[SRC_IDX:%.*]], i32 
noundef [[NELEM:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    call void @llvm.wasm.table.copy(ptr addrspace(1) @table, ptr 
addrspace(1) @other_table, i32 [[SRC_IDX]], i32 [[DST_IDX]], i32 [[NELEM]])
+// CHECK-NEXT:    ret void
+//
+void test_table_copy(int dst_idx, int src_idx, int nelem) {
+  __builtin_wasm_table_copy(table, other_table, dst_idx, src_idx, nelem);
+}
diff --git a/clang/test/Sema/wasm-funcref-table.c 
b/clang/test/Sema/wasm-funcref-table.c
new file mode 100644
index 0000000000000..9b4d53b8bbf08
--- /dev/null
+++ b/clang/test/Sema/wasm-funcref-table.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types 
-fsyntax-only -verify %s
+
+typedef void (*__funcref fn_funcref)(void);
+
+// Valid funcref table declaration (zero-length, static)
+static fn_funcref valid_table[0]; // no error expected
+
+// Invalid: non-zero length
+static fn_funcref bad_table[1]; // expected-error {{only zero-length 
WebAssembly tables are currently supported}}
+
+// Array subscript on funcref table should be rejected
+void test_subscript(void) {
+  (void)valid_table[0]; // expected-error {{cannot subscript a WebAssembly 
table}}
+}
+
+// Original reproducer from https://github.com/llvm/llvm-project/issues/140933
+// The declaration should be rejected (not static, non-zero length)
+extern fn_funcref issue_table[1]; // expected-error {{WebAssembly table must 
be static}}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to