[clang] [llvm] [WebAssembly] Add support for nonnull_extern_ref type (PR #148935)
Jasmine Tang via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 10 21:07:00 PDT 2025
https://github.com/badumbatish updated https://github.com/llvm/llvm-project/pull/148935
>From a093a778ee8c1660896ab72bbbaaac6e62965216 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 22 Jul 2025 11:38:59 -0700
Subject: [PATCH 1/4] Precommit test for nonnull extern ref
---
.../test/CodeGen/WebAssembly/wasm-externref.c | 47 +++++++++++
clang/test/Sema/wasm-refs-and-tables.c | 80 +++++++++++++++++++
2 files changed, 127 insertions(+)
diff --git a/clang/test/CodeGen/WebAssembly/wasm-externref.c b/clang/test/CodeGen/WebAssembly/wasm-externref.c
index 788438bb4a86a..1bc9f74f46074 100644
--- a/clang/test/CodeGen/WebAssembly/wasm-externref.c
+++ b/clang/test/CodeGen/WebAssembly/wasm-externref.c
@@ -2,8 +2,10 @@
// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
typedef __externref_t externref_t;
+typedef __non_null_externref_t nn_externref_t;
void helper(externref_t);
+void helper_2(nn_externref_t);
// CHECK-LABEL: @handle(
// CHECK-NEXT: entry:
@@ -16,3 +18,48 @@ void helper(externref_t);
void handle(externref_t obj) {
helper(obj);
}
+
+
+// CHECK-LABEL: @handle_2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[OBJ_ADDR:%.*]] = alloca ptr addrspace(11), align 1
+// CHECK-NEXT: store ptr addrspace(11) [[OBJ:%.*]], ptr [[OBJ_ADDR]], align 1
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(11), ptr [[OBJ_ADDR]], align 1
+// CHECK-NEXT: call void @helper_2(ptr addrspace(11) [[TMP0]])
+// CHECK-NEXT: ret void
+//
+void handle_2(nn_externref_t obj) {
+ helper_2(obj);
+}
+
+
+nn_externref_t socketpair_js_concat(nn_externref_t, nn_externref_t)
+__attribute__((import_module("wasm:js-string"), import_name("concat")));
+
+nn_externref_t get_string_ref(const char *s);
+void print_string_ref(nn_externref_t);
+
+// CHECK-LABEL: @socketpair_example(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[STR1:%.*]] = alloca ptr addrspace(11), align 1
+// CHECK-NEXT: [[STR2:%.*]] = alloca ptr addrspace(11), align 1
+// CHECK-NEXT: [[RESULT:%.*]] = alloca ptr addrspace(11), align 1
+// CHECK-NEXT: [[CALL:%.*]] = call ptr addrspace(11) @get_string_ref(ptr noundef @.str)
+// CHECK-NEXT: store ptr addrspace(11) [[CALL]], ptr [[STR1]], align 1
+// CHECK-NEXT: [[CALL1:%.*]] = call ptr addrspace(11) @get_string_ref(ptr noundef @.str.1)
+// CHECK-NEXT: store ptr addrspace(11) [[CALL1]], ptr [[STR2]], align 1
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(11), ptr [[STR1]], align 1
+// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(11), ptr [[STR2]], align 1
+// CHECK-NEXT: [[CALL2:%.*]] = call ptr addrspace(11) @socketpair_js_concat(ptr addrspace(11) [[TMP0]], ptr addrspace(11) [[TMP1]])
+// CHECK-NEXT: store ptr addrspace(11) [[CALL2]], ptr [[RESULT]], align 1
+// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(11), ptr [[RESULT]], align 1
+// CHECK-NEXT: call void @print_string_ref(ptr addrspace(11) [[TMP2]])
+// CHECK-NEXT: ret void
+//
+void socketpair_example() {
+ nn_externref_t str1 = get_string_ref("Hello, ");
+ nn_externref_t str2 = get_string_ref("world!");
+ nn_externref_t result = socketpair_js_concat(str1, str2);
+ print_string_ref(result);
+}
+
diff --git a/clang/test/Sema/wasm-refs-and-tables.c b/clang/test/Sema/wasm-refs-and-tables.c
index dd8536c52cd03..09ddbf5798f61 100644
--- a/clang/test/Sema/wasm-refs-and-tables.c
+++ b/clang/test/Sema/wasm-refs-and-tables.c
@@ -1,3 +1,4 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// RUN: %clang_cc1 -fsyntax-only -verify=expected,conly -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
// RUN: %clang_cc1 -x c++ -std=c++17 -fsyntax-only -verify=expected,cpp -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
@@ -9,6 +10,10 @@ __externref_t r1;
extern __externref_t r2;
static __externref_t r3;
+__non_null_externref_t nn_r1; // expected-error {{unknown type name '__non_null_externref_t'}}
+extern __non_null_externref_t nn_r2; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t nn_r3; // expected-error {{unknown type name '__non_null_externref_t'}}
+
__externref_t *t1; // expected-error {{pointer to WebAssembly reference type is not allowed}}
__externref_t **t2; // expected-error {{pointer to WebAssembly reference type is not allowed}}
__externref_t ******t3; // expected-error {{pointer to WebAssembly reference type is not allowed}}
@@ -19,10 +24,28 @@ __externref_t t7[0]; // expected-error {{WebAssembly table must be s
static __externref_t t8[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
static __externref_t (*t9)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
+__non_null_externref_t *nn_t1; // expected-error {{unknown type name '__non_null_externref_t'}}
+__non_null_externref_t **nn_t2; // expected-error {{unknown type name '__non_null_externref_t'}}
+__non_null_externref_t ******nn_t3; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t nn_t4[3]; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t nn_t5[]; // expected-error {{unknown type name '__non_null_externref_t'}} \
+ // cpp-error {{definition of variable with array type needs an explicit size or an initializer}}
+static __non_null_externref_t nn_t6[] = {0}; // expected-error {{unknown type name '__non_null_externref_t'}}
+__non_null_externref_t nn_t7[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t nn_t8[0][0]; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t (*nn_t9)[0]; // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
+ // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
+ // conly-error {{function cannot return array type 'int[0]'}} \
+ // cpp-error {{unknown type name '__non_null_externref_t'}}
+
static __externref_t table[0];
static __externref_t other_table[0] = {};
static __externref_t another_table[] = {}; // expected-error {{only zero-length WebAssembly tables are currently supported}}
+static __non_null_externref_t nn_table[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t nn_other_table[0] = {}; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t nn_another_table[] = {}; // expected-error {{unknown type name '__non_null_externref_t'}}
+
struct s {
__externref_t f1; // expected-error {{field has sizeless type '__externref_t'}}
__externref_t f2[0]; // expected-error {{field has sizeless type '__externref_t'}}
@@ -33,6 +56,19 @@ struct s {
__externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
};
+
+struct nn_s {
+ __non_null_externref_t nn_f1; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f2[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f3[]; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f4[0][0]; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t *nn_f5; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t ****nn_f6; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t (*nn_f7)[0]; // conly-error {{type name requires a specifier or qualifier}} \
+ // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
+ // cpp-error {{unknown type name '__non_null_externref_t'}}
+};
+
union u {
__externref_t f1; // expected-error {{field has sizeless type '__externref_t'}}
__externref_t f2[0]; // expected-error {{field has sizeless type '__externref_t'}}
@@ -43,6 +79,19 @@ union u {
__externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
};
+
+union nn_u {
+ __non_null_externref_t nn_f1; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f2[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f3[]; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f4[0][0]; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t *nn_f5; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t ****nn_f6; // expected-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t (*f7)[0]; // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
+ // conly-error {{type name requires a specifier or qualifier}} \
+ // cpp-error {{unknown type name '__non_null_externref_t'}}
+};
+
void illegal_argument_1(__externref_t table[]); // expected-error {{cannot use WebAssembly table as a function parameter}}
void illegal_argument_2(__externref_t table[0][0]); // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
void illegal_argument_3(__externref_t *table); // expected-error {{pointer to WebAssembly reference type is not allowed}}
@@ -50,10 +99,28 @@ void illegal_argument_4(__externref_t ***table); // expected-error {{pointer
void illegal_argument_5(__externref_t (*table)[0]); // expected-error {{cannot form a pointer to a WebAssembly table}}
void illegal_argument_6(__externref_t table[0]); // expected-error {{cannot use WebAssembly table as a function parameter}}
+void illegal_nn_argument_1(__non_null_externref_t table[]); // expected-error {{unknown type name '__non_null_externref_t'}}
+void illegal_nn_argument_2(__non_null_externref_t table[0][0]); // expected-error {{unknown type name '__non_null_externref_t'}}
+void illegal_nn_argument_3(__non_null_externref_t *table); // expected-error {{unknown type name '__non_null_externref_t'}}
+void illegal_nn_argument_4(__non_null_externref_t ***table); // expected-error {{unknown type name '__non_null_externref_t'}}
+void illegal_nn_argument_5(__non_null_externref_t (*table)[0]); // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
+ // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
+ // conly-error {{function cannot return array type 'int[0]'}} \
+ // cpp-error {{variable has incomplete type 'void'}} \
+ // cpp-error {{use of undeclared identifier '__non_null_externref_t'}}
+void illegal_nn_argument_6(__non_null_externref_t table[0]); // expected-error {{unknown type name '__non_null_externref_t'}}
+
__externref_t *illegal_return_1(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
__externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
__externref_t (*illegal_return_3())[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
+__non_null_externref_t *illegal_nn_return_1(); // expected-error {{unknown type name '__non_null_externref_t'}}
+__non_null_externref_t ***illegal_nn_return_2(); // expected-error {{unknown type name '__non_null_externref_t'}}
+__non_null_externref_t (*illegal_nn_return_3())[0]; // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
+ // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
+ // conly-error {{function cannot return array type 'int[0]'}} \
+ // cpp-error {{unknown type name '__non_null_externref_t'}}
+
void varargs(int, ...);
typedef void (*__funcref funcref_t)();
typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
@@ -133,3 +200,16 @@ void foo() {
void *ret_void_ptr() {
return table; // expected-error {{cannot return a WebAssembly table}}
}
+
+// checks all related assignment from extern ref to non null extern ref and vice versa
+void externref_assignment(__externref_t er, __non_null_externref_t nn_er) { // expected-error {{unknown type name '__non_null_externref_t'}}
+ __externref_t asg_1 = er;
+ __externref_t asg_2 = nn_er;
+
+ __non_null_externref_t nn_asg_1 = er; // conly-error {{expected ';' after expression}} \
+ // conly-error {{use of undeclared identifier 'nn_asg_1'}} \
+ // cpp-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_asg_2 = nn_er; // conly-error {{expected ';' after expression}} \
+ // conly-error {{use of undeclared identifier 'nn_asg_2'}} \
+ // cpp-error {{unknown type name '__non_null_externref_t'}}
+}
>From d57b88fa7be3981dc2a9b9d2307447333ecb24f5 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 22 Jul 2025 11:39:08 -0700
Subject: [PATCH 2/4] ok
---
clang/include/clang/AST/ASTContext.h | 3 +
clang/include/clang/AST/Type.h | 6 +
.../clang/Basic/WebAssemblyReferenceTypes.def | 2 +
clang/lib/AST/ASTContext.cpp | 4 +-
clang/lib/AST/Type.cpp | 13 +-
clang/lib/CodeGen/CodeGenTypes.cpp | 3 +
clang/lib/CodeGen/TargetInfo.h | 4 +
clang/lib/CodeGen/Targets/WebAssembly.cpp | 3 +
clang/lib/Sema/SemaDecl.cpp | 5 +
clang/lib/Sema/SemaExpr.cpp | 5 +
clang/test/Sema/wasm-refs-and-tables.c | 117 ++++++++----------
llvm/include/llvm/CodeGen/ValueTypes.td | 1 +
llvm/include/llvm/IR/Intrinsics.td | 1 +
llvm/include/llvm/IR/IntrinsicsWebAssembly.td | 5 +
llvm/include/llvm/IR/Type.h | 1 +
llvm/lib/IR/Type.cpp | 6 +
16 files changed, 110 insertions(+), 69 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 2b9cd035623cc..398e878dff90a 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1675,6 +1675,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Return a WebAssembly externref type.
QualType getWebAssemblyExternrefType() const;
+ /// Return a WebAssembly non null externref type.
+ QualType getWebAssemblyNonNullExternrefType() const;
+
/// Return the unique reference to a vector type of the specified
/// element type and size.
///
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 21b97102db95a..3e35fa655c4d5 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1145,6 +1145,9 @@ class QualType {
/// Returns true if it is a WebAssembly Externref Type.
bool isWebAssemblyExternrefType() const;
+ /// Returns true if it is a WebAssembly non null Externref Type.
+ bool isWebAssemblyNonNullExternrefType() const;
+
/// Returns true if it is a WebAssembly Funcref Type.
bool isWebAssemblyFuncrefType() const;
@@ -2402,6 +2405,9 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
/// Check if this is a WebAssembly Externref Type.
bool isWebAssemblyExternrefType() const;
+ /// Check if this is a WebAssembly non null Externref Type.
+ bool isWebAssemblyNonNullExternrefType() const;
+
/// Returns true if this is a WebAssembly table type: either an array of
/// reference types, or a pointer to a reference type (which can only be
/// created by array to pointer decay).
diff --git a/clang/include/clang/Basic/WebAssemblyReferenceTypes.def b/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
index 7c83da15150ce..747eb4034f669 100644
--- a/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
+++ b/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
@@ -36,5 +36,7 @@
WASM_REF_TYPE("__externref_t", "externref_t", WasmExternRef, WasmExternRefTy, 10)
+WASM_REF_TYPE("__non_null_externref_t", "non_null_externref_t", WasmNonNullExternRef, WasmNonNullExternRefTy, 10)
+
#undef WASM_TYPE
#undef WASM_REF_TYPE
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 679812adcdf12..2322c5112eb73 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3550,6 +3550,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
#include "clang/Basic/AMDGPUTypes.def"
case BuiltinType::WasmExternRef:
+ case BuiltinType::WasmNonNullExternRef:
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
llvm_unreachable("not yet implemented");
@@ -4584,7 +4585,8 @@ ASTContext::getBuiltinVectorTypeInfo(const BuiltinType *Ty) const {
QualType ASTContext::getWebAssemblyExternrefType() const {
if (Target->getTriple().isWasm() && Target->hasFeature("reference-types")) {
#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
- if (BuiltinType::Id == BuiltinType::WasmExternRef) \
+ if (BuiltinType::Id == BuiltinType::WasmExternRef || \
+ BuiltinType::Id == BuiltinType::WasmNonNullExternRef) \
return SingletonId;
#include "clang/Basic/WebAssemblyReferenceTypes.def"
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e5a1ab2ff8906..b2302311ef291 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2553,6 +2553,12 @@ bool Type::isWebAssemblyExternrefType() const {
return false;
}
+bool Type::isWebAssemblyNonNullExternrefType() const {
+ if (const auto *BT = getAs<BuiltinType>())
+ return BT->getKind() == BuiltinType::WasmNonNullExternRef;
+ return false;
+}
+
bool Type::isWebAssemblyTableType() const {
if (const auto *ATy = dyn_cast<ArrayType>(this))
return ATy->getElementType().isWebAssemblyReferenceType();
@@ -2922,13 +2928,18 @@ bool QualType::hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD) {
}
bool QualType::isWebAssemblyReferenceType() const {
- return isWebAssemblyExternrefType() || isWebAssemblyFuncrefType();
+ return isWebAssemblyExternrefType() || isWebAssemblyNonNullExternrefType() ||
+ isWebAssemblyFuncrefType();
}
bool QualType::isWebAssemblyExternrefType() const {
return getTypePtr()->isWebAssemblyExternrefType();
}
+bool QualType::isWebAssemblyNonNullExternrefType() const {
+ return getTypePtr()->isWebAssemblyNonNullExternrefType();
+}
+
bool QualType::isWebAssemblyFuncrefType() const {
return getTypePtr()->isFunctionPointerType() &&
getAddressSpace() == LangAS::wasm_funcref;
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index c98503e4bbd26..515a756c7a755 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -569,6 +569,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case BuiltinType::Id: { \
if (BuiltinType::Id == BuiltinType::WasmExternRef) \
ResultType = CGM.getTargetCodeGenInfo().getWasmExternrefReferenceType(); \
+ else if (BuiltinType::Id == BuiltinType::WasmNonNullExternRef) \
+ ResultType = \
+ CGM.getTargetCodeGenInfo().getWasmNonNullExternrefReferenceType(); \
else \
llvm_unreachable("Unexpected wasm reference builtin type!"); \
} break;
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index b4057d369f988..a416e4127ff13 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -418,6 +418,10 @@ class TargetCodeGenInfo {
/// Return the WebAssembly externref reference type.
virtual llvm::Type *getWasmExternrefReferenceType() const { return nullptr; }
+ /// Return the WebAssembly externref reference type.
+ virtual llvm::Type *getWasmNonNullExternrefReferenceType() const {
+ return nullptr;
+ }
/// Return the WebAssembly funcref reference type.
virtual llvm::Type *getWasmFuncrefReferenceType() const { return nullptr; }
diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp
index 9217c78a540a3..054dd7c66455c 100644
--- a/clang/lib/CodeGen/Targets/WebAssembly.cpp
+++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp
@@ -89,6 +89,9 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo {
virtual llvm::Type *getWasmExternrefReferenceType() const override {
return llvm::Type::getWasm_ExternrefTy(getABIInfo().getVMContext());
}
+ virtual llvm::Type *getWasmNonNullExternrefReferenceType() const override {
+ return llvm::Type::getWasm_NonNullExternrefTy(getABIInfo().getVMContext());
+ }
/// Return the WebAssembly funcref reference type.
virtual llvm::Type *getWasmFuncrefReferenceType() const override {
return llvm::Type::getWasm_FuncrefTy(getABIInfo().getVMContext());
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 11cbda412667f..bb41c30e0eeae 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13643,6 +13643,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
return;
}
+ if (VDecl->getType().isWebAssemblyExternrefType() && Init->getType()->isWebAssemblyNonNullExternrefType()) {
+ VDecl->setInit(Init);
+ return;
+ }
+
// C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (VDecl->getType()->isUndeducedType()) {
if (Init->containsErrors()) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 01df1913339d9..a3bf2db4bb6c7 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9638,6 +9638,11 @@ AssignConvertType Sema::CheckAssignmentConstraints(QualType LHSType,
return AssignConvertType::Compatible;
}
+ if (LHSType->isWebAssemblyExternrefType() && RHSType->isWebAssemblyNonNullExternrefType()) {
+ Kind = CK_NoOp;
+ return AssignConvertType::Compatible;
+ }
+
return AssignConvertType::Incompatible;
}
diff --git a/clang/test/Sema/wasm-refs-and-tables.c b/clang/test/Sema/wasm-refs-and-tables.c
index 09ddbf5798f61..2c5b8307998b1 100644
--- a/clang/test/Sema/wasm-refs-and-tables.c
+++ b/clang/test/Sema/wasm-refs-and-tables.c
@@ -1,4 +1,3 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// RUN: %clang_cc1 -fsyntax-only -verify=expected,conly -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
// RUN: %clang_cc1 -x c++ -std=c++17 -fsyntax-only -verify=expected,cpp -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
@@ -10,9 +9,9 @@ __externref_t r1;
extern __externref_t r2;
static __externref_t r3;
-__non_null_externref_t nn_r1; // expected-error {{unknown type name '__non_null_externref_t'}}
-extern __non_null_externref_t nn_r2; // expected-error {{unknown type name '__non_null_externref_t'}}
-static __non_null_externref_t nn_r3; // expected-error {{unknown type name '__non_null_externref_t'}}
+__non_null_externref_t nn_r1;
+extern __non_null_externref_t nn_r2;
+static __non_null_externref_t nn_r3;
__externref_t *t1; // expected-error {{pointer to WebAssembly reference type is not allowed}}
__externref_t **t2; // expected-error {{pointer to WebAssembly reference type is not allowed}}
@@ -24,27 +23,23 @@ __externref_t t7[0]; // expected-error {{WebAssembly table must be s
static __externref_t t8[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
static __externref_t (*t9)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
-__non_null_externref_t *nn_t1; // expected-error {{unknown type name '__non_null_externref_t'}}
-__non_null_externref_t **nn_t2; // expected-error {{unknown type name '__non_null_externref_t'}}
-__non_null_externref_t ******nn_t3; // expected-error {{unknown type name '__non_null_externref_t'}}
-static __non_null_externref_t nn_t4[3]; // expected-error {{unknown type name '__non_null_externref_t'}}
-static __non_null_externref_t nn_t5[]; // expected-error {{unknown type name '__non_null_externref_t'}} \
- // cpp-error {{definition of variable with array type needs an explicit size or an initializer}}
-static __non_null_externref_t nn_t6[] = {0}; // expected-error {{unknown type name '__non_null_externref_t'}}
-__non_null_externref_t nn_t7[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
-static __non_null_externref_t nn_t8[0][0]; // expected-error {{unknown type name '__non_null_externref_t'}}
-static __non_null_externref_t (*nn_t9)[0]; // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
- // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
- // conly-error {{function cannot return array type 'int[0]'}} \
- // cpp-error {{unknown type name '__non_null_externref_t'}}
+__non_null_externref_t *nn_t1; // expected-error {{pointer to WebAssembly reference type is not allowed}}
+__non_null_externref_t **nn_t2; // expected-error {{pointer to WebAssembly reference type is not allowed}}
+__non_null_externref_t ******nn_t3; // expected-error {{pointer to WebAssembly reference type is not allowed}}
+static __non_null_externref_t nn_t4[3]; // expected-error {{only zero-length WebAssembly tables are currently supported}}
+static __non_null_externref_t nn_t5[]; // expected-error {{only zero-length WebAssembly tables are currently supported}}
+static __non_null_externref_t nn_t6[] = {0}; // expected-error {{only zero-length WebAssembly tables are currently supported}}
+__non_null_externref_t nn_t7[0]; // expected-error {{WebAssembly table must be static}}
+static __non_null_externref_t nn_t8[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
+static __non_null_externref_t (*nn_t9)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
static __externref_t table[0];
static __externref_t other_table[0] = {};
static __externref_t another_table[] = {}; // expected-error {{only zero-length WebAssembly tables are currently supported}}
-static __non_null_externref_t nn_table[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
-static __non_null_externref_t nn_other_table[0] = {}; // expected-error {{unknown type name '__non_null_externref_t'}}
-static __non_null_externref_t nn_another_table[] = {}; // expected-error {{unknown type name '__non_null_externref_t'}}
+static __non_null_externref_t nn_table[0];
+static __non_null_externref_t nn_other_table[0] = {};
+static __non_null_externref_t nn_another_table[] = {}; // expected-error {{only zero-length WebAssembly tables are currently supported}}
struct s {
__externref_t f1; // expected-error {{field has sizeless type '__externref_t'}}
@@ -58,15 +53,13 @@ struct s {
struct nn_s {
- __non_null_externref_t nn_f1; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t nn_f2[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t nn_f3[]; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t nn_f4[0][0]; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t *nn_f5; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t ****nn_f6; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t (*nn_f7)[0]; // conly-error {{type name requires a specifier or qualifier}} \
- // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
- // cpp-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f1; // expected-error {{field has sizeless type '__non_null_externref_t'}}
+ __non_null_externref_t nn_f2[0]; // expected-error {{field has sizeless type '__non_null_externref_t'}}
+ __non_null_externref_t nn_f3[]; // expected-error {{field has sizeless type '__non_null_externref_t'}}
+ __non_null_externref_t nn_f4[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
+ __non_null_externref_t *nn_f5; // expected-error {{pointer to WebAssembly reference type is not allowed}}
+ __non_null_externref_t ****nn_f6; // expected-error {{pointer to WebAssembly reference type is not allowed}}
+ __non_null_externref_t (*nn_f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
};
union u {
@@ -81,15 +74,13 @@ union u {
union nn_u {
- __non_null_externref_t nn_f1; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t nn_f2[0]; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t nn_f3[]; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t nn_f4[0][0]; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t *nn_f5; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t ****nn_f6; // expected-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t (*f7)[0]; // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
- // conly-error {{type name requires a specifier or qualifier}} \
- // cpp-error {{unknown type name '__non_null_externref_t'}}
+ __non_null_externref_t nn_f1; // expected-error {{field has sizeless type '__non_null_externref_t'}}
+ __non_null_externref_t nn_f2[0]; // expected-error {{field has sizeless type '__non_null_externref_t'}}
+ __non_null_externref_t nn_f3[]; // expected-error {{field has sizeless type '__non_null_externref_t'}}
+ __non_null_externref_t nn_f4[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
+ __non_null_externref_t *nn_f5; // expected-error {{pointer to WebAssembly reference type is not allowed}}
+ __non_null_externref_t ****nn_f6; // expected-error {{pointer to WebAssembly reference type is not allowed}}
+ __non_null_externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
};
void illegal_argument_1(__externref_t table[]); // expected-error {{cannot use WebAssembly table as a function parameter}}
@@ -98,28 +89,21 @@ void illegal_argument_3(__externref_t *table); // expected-error {{pointer
void illegal_argument_4(__externref_t ***table); // expected-error {{pointer to WebAssembly reference type is not allowed}}
void illegal_argument_5(__externref_t (*table)[0]); // expected-error {{cannot form a pointer to a WebAssembly table}}
void illegal_argument_6(__externref_t table[0]); // expected-error {{cannot use WebAssembly table as a function parameter}}
-
-void illegal_nn_argument_1(__non_null_externref_t table[]); // expected-error {{unknown type name '__non_null_externref_t'}}
-void illegal_nn_argument_2(__non_null_externref_t table[0][0]); // expected-error {{unknown type name '__non_null_externref_t'}}
-void illegal_nn_argument_3(__non_null_externref_t *table); // expected-error {{unknown type name '__non_null_externref_t'}}
-void illegal_nn_argument_4(__non_null_externref_t ***table); // expected-error {{unknown type name '__non_null_externref_t'}}
-void illegal_nn_argument_5(__non_null_externref_t (*table)[0]); // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
- // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
- // conly-error {{function cannot return array type 'int[0]'}} \
- // cpp-error {{variable has incomplete type 'void'}} \
- // cpp-error {{use of undeclared identifier '__non_null_externref_t'}}
-void illegal_nn_argument_6(__non_null_externref_t table[0]); // expected-error {{unknown type name '__non_null_externref_t'}}
+
+void illegal_nn_argument_1(__non_null_externref_t table[]); // expected-error {{cannot use WebAssembly table as a function parameter}}
+void illegal_nn_argument_2(__non_null_externref_t table[0][0]); // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
+void illegal_nn_argument_3(__non_null_externref_t *table); // expected-error {{pointer to WebAssembly reference type is not allowed}}
+void illegal_nn_argument_4(__non_null_externref_t ***table); // expected-error {{pointer to WebAssembly reference type is not allowed}}
+void illegal_nn_argument_5(__non_null_externref_t (*table)[0]); // expected-error {{cannot form a pointer to a WebAssembly table}}
+void illegal_nn_argument_6(__non_null_externref_t table[0]); // expected-error {{cannot use WebAssembly table as a function parameter}}
__externref_t *illegal_return_1(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
__externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
__externref_t (*illegal_return_3())[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
-
-__non_null_externref_t *illegal_nn_return_1(); // expected-error {{unknown type name '__non_null_externref_t'}}
-__non_null_externref_t ***illegal_nn_return_2(); // expected-error {{unknown type name '__non_null_externref_t'}}
-__non_null_externref_t (*illegal_nn_return_3())[0]; // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
- // conly-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit in}} \
- // conly-error {{function cannot return array type 'int[0]'}} \
- // cpp-error {{unknown type name '__non_null_externref_t'}}
+
+__non_null_externref_t *illegal_nn_return_1(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
+__non_null_externref_t ***illegal_nn_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
+__non_null_externref_t (*illegal_nn_return_3())[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
void varargs(int, ...);
typedef void (*__funcref funcref_t)();
@@ -201,15 +185,14 @@ void *ret_void_ptr() {
return table; // expected-error {{cannot return a WebAssembly table}}
}
-// checks all related assignment from extern ref to non null extern ref and vice versa
-void externref_assignment(__externref_t er, __non_null_externref_t nn_er) { // expected-error {{unknown type name '__non_null_externref_t'}}
- __externref_t asg_1 = er;
- __externref_t asg_2 = nn_er;
-
- __non_null_externref_t nn_asg_1 = er; // conly-error {{expected ';' after expression}} \
- // conly-error {{use of undeclared identifier 'nn_asg_1'}} \
- // cpp-error {{unknown type name '__non_null_externref_t'}}
- __non_null_externref_t nn_asg_2 = nn_er; // conly-error {{expected ';' after expression}} \
- // conly-error {{use of undeclared identifier 'nn_asg_2'}} \
- // cpp-error {{unknown type name '__non_null_externref_t'}}
+// checks all related assignment from extern ref to non null extern ref and vice versa
+void externref_assignment(__externref_t er, __non_null_externref_t nn_er) {
+ __externref_t asg_1 = er;
+ __externref_t asg_2 = nn_er;
+
+ __non_null_externref_t nn_asg_1 = er; // conly-error {{initializing '__non_null_externref_t' with an expression of incompatible type '__externref_t'}} \
+ // cpp-error {{cannot initialize a variable of type '__non_null_externref_t' with an lvalue of type '__externref_t'}}
+ __non_null_externref_t nn_asg_2 = nn_er;
+
+
}
diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td
index 4551e7e4b9b60..42df9fc580de8 100644
--- a/llvm/include/llvm/CodeGen/ValueTypes.td
+++ b/llvm/include/llvm/CodeGen/ValueTypes.td
@@ -330,6 +330,7 @@ def untyped : ValueType<8, 231> { // Produces an untyped value
}
def funcref : ValueType<0, 232>; // WebAssembly's funcref type
def externref : ValueType<0, 233>; // WebAssembly's externref type
+def externref_nn : ValueType<0, 242>; // WebAssembly's nonnull externref type
def exnref : ValueType<0, 234>; // WebAssembly's exnref type
def x86amx : ValueType<8192, 235>; // X86 AMX value
def i64x8 : ValueType<512, 236>; // 8 Consecutive GPRs (AArch64)
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index bd6f94ac1286c..feb83d8d0291c 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -616,6 +616,7 @@ def llvm_v16f64_ty : LLVMType<v16f64>; // 16 x double
def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
def llvm_externref_ty : LLVMType<externref>;
+def llvm_externref_nn_ty : LLVMType<externref_nn>;
def llvm_funcref_ty : LLVMType<funcref>;
def llvm_exnref_ty : LLVMType<exnref>;
diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index f592ff287a0e3..bc0f79ab4bd70 100644
--- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -29,6 +29,11 @@ def int_wasm_memory_grow :
//===----------------------------------------------------------------------===//
def int_wasm_ref_null_extern :
DefaultAttrsIntrinsic<[llvm_externref_ty], [], [IntrNoMem]>;
+
+// TODO: Is this correct?
+def int_wasm_ref_nonnull_extern
+ : DefaultAttrsIntrinsic<[llvm_externref_nn_ty], [], [IntrNoMem]>;
+
def int_wasm_ref_null_func :
DefaultAttrsIntrinsic<[llvm_funcref_ty], [], [IntrNoMem]>;
def int_wasm_ref_null_exn:
diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h
index 74dd490729741..d488b1552240a 100644
--- a/llvm/include/llvm/IR/Type.h
+++ b/llvm/include/llvm/IR/Type.h
@@ -476,6 +476,7 @@ class Type {
// Convenience methods for getting pointer types.
//
LLVM_ABI static Type *getWasm_ExternrefTy(LLVMContext &C);
+ LLVM_ABI static Type *getWasm_NonNullExternrefTy(LLVMContext &C);
LLVM_ABI static Type *getWasm_FuncrefTy(LLVMContext &C);
/// Return a pointer to the current type. This is equivalent to
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 5e1bf2863191c..9ed41f1e45ad5 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -308,6 +308,12 @@ Type *Type::getWasm_ExternrefTy(LLVMContext &C) {
return Ty;
}
+Type *Type::getWasm_NonNullExternrefTy(LLVMContext &C) {
+ // opaque pointer in addrspace(11)
+ static PointerType *Ty = PointerType::get(C, 11);
+ return Ty;
+}
+
Type *Type::getWasm_FuncrefTy(LLVMContext &C) {
// opaque pointer in addrspace(20)
static PointerType *Ty = PointerType::get(C, 20);
>From 2380d3e23698f64bf84e975e94ee1654154e5a11 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 22 Jul 2025 13:12:28 -0700
Subject: [PATCH 3/4] Reformatted changes
---
clang/lib/Sema/SemaDecl.cpp | 3 ++-
clang/lib/Sema/SemaExpr.cpp | 3 ++-
llvm/include/llvm/IR/Intrinsics.td | 2 +-
llvm/include/llvm/IR/IntrinsicsWebAssembly.td | 2 +-
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index bb41c30e0eeae..807a385b83fe0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13643,7 +13643,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
return;
}
- if (VDecl->getType().isWebAssemblyExternrefType() && Init->getType()->isWebAssemblyNonNullExternrefType()) {
+ if (VDecl->getType().isWebAssemblyExternrefType() &&
+ Init->getType()->isWebAssemblyNonNullExternrefType()) {
VDecl->setInit(Init);
return;
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a3bf2db4bb6c7..da38a5a5ff056 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9638,7 +9638,8 @@ AssignConvertType Sema::CheckAssignmentConstraints(QualType LHSType,
return AssignConvertType::Compatible;
}
- if (LHSType->isWebAssemblyExternrefType() && RHSType->isWebAssemblyNonNullExternrefType()) {
+ if (LHSType->isWebAssemblyExternrefType() &&
+ RHSType->isWebAssemblyNonNullExternrefType()) {
Kind = CK_NoOp;
return AssignConvertType::Compatible;
}
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index feb83d8d0291c..fe4d20dba7484 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -616,7 +616,7 @@ def llvm_v16f64_ty : LLVMType<v16f64>; // 16 x double
def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
def llvm_externref_ty : LLVMType<externref>;
-def llvm_externref_nn_ty : LLVMType<externref_nn>;
+def llvm_externref_nn_ty : LLVMType<externref_nn>;
def llvm_funcref_ty : LLVMType<funcref>;
def llvm_exnref_ty : LLVMType<exnref>;
diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index bc0f79ab4bd70..1e910d418066c 100644
--- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -32,7 +32,7 @@ def int_wasm_ref_null_extern :
// TODO: Is this correct?
def int_wasm_ref_nonnull_extern
- : DefaultAttrsIntrinsic<[llvm_externref_nn_ty], [], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_externref_nn_ty], [], [IntrNoMem]>;
def int_wasm_ref_null_func :
DefaultAttrsIntrinsic<[llvm_funcref_ty], [], [IntrNoMem]>;
>From d48916c1cdc5793736faedcc244e3a48344f7f70 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Tue, 22 Jul 2025 14:57:26 -0700
Subject: [PATCH 4/4] Put AS 11 for nn extern ref
---
clang/include/clang/Basic/WebAssemblyReferenceTypes.def | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/WebAssemblyReferenceTypes.def b/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
index 747eb4034f669..296bc45cff4c9 100644
--- a/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
+++ b/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
@@ -36,7 +36,7 @@
WASM_REF_TYPE("__externref_t", "externref_t", WasmExternRef, WasmExternRefTy, 10)
-WASM_REF_TYPE("__non_null_externref_t", "non_null_externref_t", WasmNonNullExternRef, WasmNonNullExternRefTy, 10)
+WASM_REF_TYPE("__non_null_externref_t", "non_null_externref_t", WasmNonNullExternRef, WasmNonNullExternRefTy, 11)
#undef WASM_TYPE
#undef WASM_REF_TYPE
More information about the llvm-commits
mailing list