Skip to content

Commit e29b70e

Browse files
authored
[WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (#139580)
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.
1 parent 1a0b825 commit e29b70e

File tree

7 files changed

+36
-1
lines changed

7 files changed

+36
-1
lines changed

clang/include/clang/Basic/BuiltinsWebAssembly.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ TARGET_BUILTIN(__builtin_wasm_replace_lane_f16x8, "V8hV8hIif", "nc", "fp16")
192192
// in which case the argument spec (second argument) is unused.
193193

194194
TARGET_BUILTIN(__builtin_wasm_ref_null_extern, "i", "nct", "reference-types")
195+
TARGET_BUILTIN(__builtin_wasm_ref_is_null_extern, "ii", "nct", "reference-types")
195196

196197
// A funcref represented as a function pointer with the funcref attribute
197198
// attached to the type, therefore SemaChecking will check for the right

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13012,6 +13012,8 @@ def err_wasm_reftype_multidimensional_array : Error<
1301213012
"multi-dimensional arrays of WebAssembly references are not allowed">;
1301313013
def err_wasm_builtin_arg_must_be_table_type : Error <
1301413014
"%ordinal0 argument must be a WebAssembly table">;
13015+
def err_wasm_builtin_arg_must_be_externref_type : Error <
13016+
"%ordinal0 argument must be an externref">;
1301513017
def err_wasm_builtin_arg_must_match_table_element_type : Error <
1301613018
"%ordinal0 argument must match the element type of the WebAssembly table in the %ordinal1 argument">;
1301713019
def err_wasm_builtin_arg_must_be_integer_type : Error <

clang/include/clang/Sema/SemaWasm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class SemaWasm : public SemaBase {
2929
CallExpr *TheCall);
3030

3131
bool BuiltinWasmRefNullExtern(CallExpr *TheCall);
32+
bool BuiltinWasmRefIsNullExtern(CallExpr *TheCall);
3233
bool BuiltinWasmRefNullFunc(CallExpr *TheCall);
3334
bool BuiltinWasmTableGet(CallExpr *TheCall);
3435
bool BuiltinWasmTableSet(CallExpr *TheCall);

clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
209209
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_extern);
210210
return Builder.CreateCall(Callee);
211211
}
212+
case WebAssembly::BI__builtin_wasm_ref_is_null_extern: {
213+
Value *Src = EmitScalarExpr(E->getArg(0));
214+
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_is_null_extern);
215+
return Builder.CreateCall(Callee, {Src});
216+
}
212217
case WebAssembly::BI__builtin_wasm_ref_null_func: {
213218
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_func);
214219
return Builder.CreateCall(Callee);

clang/lib/Sema/SemaWasm.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,27 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E,
5454
bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) {
5555
if (SemaRef.checkArgCount(TheCall, /*DesiredArgCount=*/0))
5656
return true;
57-
5857
TheCall->setType(getASTContext().getWebAssemblyExternrefType());
5958

6059
return false;
6160
}
6261

62+
bool SemaWasm::BuiltinWasmRefIsNullExtern(CallExpr *TheCall) {
63+
if (SemaRef.checkArgCount(TheCall, 1)) {
64+
return true;
65+
}
66+
67+
Expr *ArgExpr = TheCall->getArg(0);
68+
if (!ArgExpr->getType().isWebAssemblyExternrefType()) {
69+
SemaRef.Diag(ArgExpr->getBeginLoc(),
70+
diag::err_wasm_builtin_arg_must_be_externref_type)
71+
<< 1 << ArgExpr->getSourceRange();
72+
return true;
73+
}
74+
75+
return false;
76+
}
77+
6378
bool SemaWasm::BuiltinWasmRefNullFunc(CallExpr *TheCall) {
6479
ASTContext &Context = getASTContext();
6580
if (SemaRef.checkArgCount(TheCall, /*DesiredArgCount=*/0))
@@ -220,6 +235,8 @@ bool SemaWasm::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
220235
return BuiltinWasmRefNullExtern(TheCall);
221236
case WebAssembly::BI__builtin_wasm_ref_null_func:
222237
return BuiltinWasmRefNullFunc(TheCall);
238+
case WebAssembly::BI__builtin_wasm_ref_is_null_extern:
239+
return BuiltinWasmRefIsNullExtern(TheCall);
223240
case WebAssembly::BI__builtin_wasm_table_get:
224241
return BuiltinWasmTableGet(TheCall);
225242
case WebAssembly::BI__builtin_wasm_table_set:

clang/test/CodeGen/builtins-wasm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,12 @@ __externref_t externref_null() {
741741
// WEBASSEMBLY-NEXT: ret
742742
}
743743

744+
int externref_is_null(__externref_t arg) {
745+
return __builtin_wasm_ref_is_null_extern(arg);
746+
// WEBASSEMBLY: tail call i32 @llvm.wasm.ref.is_null.extern(ptr addrspace(10) %arg)
747+
// WEBASSEMBLY-NEXT: ret
748+
}
749+
744750
void *tp (void) {
745751
return __builtin_thread_pointer ();
746752
// WEBASSEMBLY: call {{.*}} @llvm.thread.pointer()

clang/test/Sema/builtins-wasm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ typedef void (*__funcref funcref_t)();
88
void test_ref_null() {
99
funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
1010
__externref_t ref = __builtin_wasm_ref_null_extern(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
11+
__builtin_wasm_ref_is_null_extern(ref, 1); // expected-error {{too many arguments to function call, expected 1, have 2}}
12+
__builtin_wasm_ref_is_null_extern(); // expected-error {{too few arguments to function call, expected 1, have 0}}
13+
__builtin_wasm_ref_is_null_extern(1); // expected-error {{1st argument must be an externref}}
1114
}
1215

1316
void test_table_size(__externref_t ref, void *ptr, int arr[]) {

0 commit comments

Comments
 (0)