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/3] [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/3] 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) { >From 0258c51ca35c7bb21dc484bf9c9ca42330ab537b Mon Sep 17 00:00:00 2001 From: Hood Chatham <roberthoodchat...@gmail.com> Date: Mon, 12 May 2025 17:53:59 -0400 Subject: [PATCH 3/3] Fix Sema::checkArgCount with 0 args --- clang/lib/Sema/SemaChecking.cpp | 2 +- clang/lib/Sema/SemaWasm.cpp | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 97f623f61a405..5d0d5861d4026 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -168,7 +168,7 @@ bool Sema::checkArgCount(CallExpr *Call, unsigned DesiredArgCount) { return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args) << 0 /*function call*/ << DesiredArgCount << ArgCount - << /*is non object*/ 0 << Call->getArg(1)->getSourceRange(); + << /*is non object*/ 0 << Range; } static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S) { diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index 3842674cd9a2d..6e949290c1ca2 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -52,10 +52,7 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, } bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) { - 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; + if (SemaRef.checkArgCount(TheCall, 0)) { return true; } TheCall->setType(getASTContext().getWebAssemblyExternrefType()); @@ -81,10 +78,7 @@ bool SemaWasm::BuiltinWasmRefIsNullExtern(CallExpr *TheCall) { bool SemaWasm::BuiltinWasmRefNullFunc(CallExpr *TheCall) { ASTContext &Context = getASTContext(); - 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; + if (SemaRef.checkArgCount(TheCall, 0)) { return true; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits