https://github.com/hoodmane updated 
https://github.com/llvm/llvm-project/pull/139580

>From 2ca282f0a20088bef15289a8ce5167d1e23595c3 Mon Sep 17 00:00:00 2001
From: Hood Chatham <roberthoodchat...@gmail.com>
Date: Fri, 9 May 2025 00:16:26 -0400
Subject: [PATCH 1/2] [Wasm][Clang] Add  __builtin_wasm_ref_is_null_extern

I also fixed __builtin_wasm_ref_null_extern() to generate a diagnostic
when it gets an argument. It seems like `SemaRef.checkArgCount()` has a
bug that makes it unable to check for 0 args.
---
 .../clang/Basic/BuiltinsWebAssembly.def       |  1 +
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 ++
 clang/include/clang/Sema/SemaWasm.h           |  1 +
 .../CodeGen/TargetBuiltins/WebAssembly.cpp    |  5 ++++
 clang/lib/Sema/SemaWasm.cpp                   | 26 +++++++++++++++++--
 clang/test/CodeGen/builtins-wasm.c            |  6 +++++
 clang/test/Sema/builtins-wasm.c               |  4 +++
 7 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def 
b/clang/include/clang/Basic/BuiltinsWebAssembly.def
index ab480369b3820..e2afcc08064b2 100644
--- a/clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -192,6 +192,7 @@ TARGET_BUILTIN(__builtin_wasm_replace_lane_f16x8, 
"V8hV8hIif", "nc", "fp16")
 // in which case the argument spec (second argument) is unused.
 
 TARGET_BUILTIN(__builtin_wasm_ref_null_extern, "i", "nct", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_ref_is_null_extern, "ii", "nct", 
"reference-types")
 
 // A funcref represented as a function pointer with the funcref attribute
 // attached to the type, therefore SemaChecking will check for the right
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e5a7cdc14a737..d4abc46ae58ee 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12991,6 +12991,8 @@ def err_wasm_reftype_multidimensional_array : Error<
   "multi-dimensional arrays of WebAssembly references are not allowed">;
 def err_wasm_builtin_arg_must_be_table_type : Error <
   "%ordinal0 argument must be a WebAssembly table">;
+def err_wasm_builtin_arg_must_be_externref_type : Error <
+  "%ordinal0 argument must be an externref">;
 def err_wasm_builtin_arg_must_match_table_element_type : Error <
   "%ordinal0 argument must match the element type of the WebAssembly table in 
the %ordinal1 argument">;
 def err_wasm_builtin_arg_must_be_integer_type : Error <
diff --git a/clang/include/clang/Sema/SemaWasm.h 
b/clang/include/clang/Sema/SemaWasm.h
index 8841fdff23035..2123e073516cb 100644
--- a/clang/include/clang/Sema/SemaWasm.h
+++ b/clang/include/clang/Sema/SemaWasm.h
@@ -29,6 +29,7 @@ class SemaWasm : public SemaBase {
                                            CallExpr *TheCall);
 
   bool BuiltinWasmRefNullExtern(CallExpr *TheCall);
+  bool BuiltinWasmRefIsNullExtern(CallExpr *TheCall);
   bool BuiltinWasmRefNullFunc(CallExpr *TheCall);
   bool BuiltinWasmTableGet(CallExpr *TheCall);
   bool BuiltinWasmTableSet(CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp 
b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp
index 698f43215a1be..b7fd70e855d40 100644
--- a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp
@@ -209,6 +209,11 @@ Value 
*CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_extern);
     return Builder.CreateCall(Callee);
   }
+  case WebAssembly::BI__builtin_wasm_ref_is_null_extern: {
+    Value *Src = EmitScalarExpr(E->getArg(0));
+    Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_is_null_extern);
+    return Builder.CreateCall(Callee, {Src});
+  }
   case WebAssembly::BI__builtin_wasm_ref_null_func: {
     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_func);
     return Builder.CreateCall(Callee);
diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp
index c0fa05bc17609..4157e179c97d6 100644
--- a/clang/lib/Sema/SemaWasm.cpp
+++ b/clang/lib/Sema/SemaWasm.cpp
@@ -52,14 +52,34 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr 
*E,
 }
 
 bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) {
-  if (TheCall->getNumArgs() != 0)
+  if (TheCall->getNumArgs() != 0) {
+    Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_many_args)
+        << 0 /*function call*/ << /*expected*/ 0 << TheCall->getNumArgs()
+        << /*is non object*/ 0;
     return true;
-
+  }
   TheCall->setType(getASTContext().getWebAssemblyExternrefType());
 
   return false;
 }
 
+bool SemaWasm::BuiltinWasmRefIsNullExtern(CallExpr *TheCall) {
+  if (SemaRef.checkArgCount(TheCall, 1)) {
+    return true;
+  }
+
+  Expr *ArgExpr = TheCall->getArg(0);
+  if (!ArgExpr->getType().isWebAssemblyExternrefType()) {
+    SemaRef.Diag(ArgExpr->getBeginLoc(),
+                  diag::err_wasm_builtin_arg_must_be_externref_type)
+           << 1 << ArgExpr->getSourceRange();
+    return true;
+  }
+
+  return false;
+}
+
+
 bool SemaWasm::BuiltinWasmRefNullFunc(CallExpr *TheCall) {
   ASTContext &Context = getASTContext();
   if (TheCall->getNumArgs() != 0) {
@@ -224,6 +244,8 @@ bool SemaWasm::CheckWebAssemblyBuiltinFunctionCall(const 
TargetInfo &TI,
     return BuiltinWasmRefNullExtern(TheCall);
   case WebAssembly::BI__builtin_wasm_ref_null_func:
     return BuiltinWasmRefNullFunc(TheCall);
+  case WebAssembly::BI__builtin_wasm_ref_is_null_extern:
+    return BuiltinWasmRefIsNullExtern(TheCall);
   case WebAssembly::BI__builtin_wasm_table_get:
     return BuiltinWasmTableGet(TheCall);
   case WebAssembly::BI__builtin_wasm_table_set:
diff --git a/clang/test/CodeGen/builtins-wasm.c 
b/clang/test/CodeGen/builtins-wasm.c
index 263cfd3ab4c69..4a44a9a88df11 100644
--- a/clang/test/CodeGen/builtins-wasm.c
+++ b/clang/test/CodeGen/builtins-wasm.c
@@ -741,6 +741,12 @@ __externref_t externref_null() {
   // WEBASSEMBLY-NEXT: ret
 }
 
+int externref_is_null(__externref_t arg) {
+  return __builtin_wasm_ref_is_null_extern(arg);
+  // WEBASSEMBLY: tail call i32 @llvm.wasm.ref.is_null.extern(ptr 
addrspace(10) %arg)
+  // WEBASSEMBLY-NEXT: ret
+}
+
 void *tp (void) {
   return __builtin_thread_pointer ();
   // WEBASSEMBLY: call {{.*}} @llvm.thread.pointer()
diff --git a/clang/test/Sema/builtins-wasm.c b/clang/test/Sema/builtins-wasm.c
index beb430616233a..31e5291d3ae5e 100644
--- a/clang/test/Sema/builtins-wasm.c
+++ b/clang/test/Sema/builtins-wasm.c
@@ -7,6 +7,10 @@ static __externref_t table[0];
 typedef void (*__funcref funcref_t)();
 void test_ref_null() {
   funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too 
many arguments to function call, expected 0, have 1}}
+  __externref_t ref = __builtin_wasm_ref_null_extern(0); // expected-error 
{{too many arguments to function call, expected 0, have 1}}
+  __builtin_wasm_ref_is_null_extern(ref, 1); // expected-error {{too many 
arguments to function call, expected 1, have 2}}
+  __builtin_wasm_ref_is_null_extern(); // expected-error {{too few arguments 
to function call, expected 1, have 0}}
+  __builtin_wasm_ref_is_null_extern(1); // expected-error {{1st argument must 
be an externref}}
 }
 
 void test_table_size(__externref_t ref, void *ptr, int arr[]) {

>From cfb8e469532c5bffa2b65fb4bc83cc7573b70977 Mon Sep 17 00:00:00 2001
From: Hood Chatham <roberthoodchat...@gmail.com>
Date: Mon, 12 May 2025 13:09:01 -0400
Subject: [PATCH 2/2] Apply clang-format

---
 clang/lib/Sema/SemaWasm.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp
index 4157e179c97d6..3842674cd9a2d 100644
--- a/clang/lib/Sema/SemaWasm.cpp
+++ b/clang/lib/Sema/SemaWasm.cpp
@@ -71,15 +71,14 @@ bool SemaWasm::BuiltinWasmRefIsNullExtern(CallExpr 
*TheCall) {
   Expr *ArgExpr = TheCall->getArg(0);
   if (!ArgExpr->getType().isWebAssemblyExternrefType()) {
     SemaRef.Diag(ArgExpr->getBeginLoc(),
-                  diag::err_wasm_builtin_arg_must_be_externref_type)
-           << 1 << ArgExpr->getSourceRange();
+                 diag::err_wasm_builtin_arg_must_be_externref_type)
+        << 1 << ArgExpr->getSourceRange();
     return true;
   }
 
   return false;
 }
 
-
 bool SemaWasm::BuiltinWasmRefNullFunc(CallExpr *TheCall) {
   ASTContext &Context = getASTContext();
   if (TheCall->getNumArgs() != 0) {

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to