https://github.com/Changqing-JING updated https://github.com/llvm/llvm-project/pull/221909
>From c4932a4981b7e3cedbc771cfef16c03c47732091 Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Tue, 8 Sep 2026 15:42:28 +0800 Subject: [PATCH 1/8] [Clang][WebAssembly] Add wasm_global declaration attribute --- clang/include/clang/Basic/Attr.td | 6 ++++++ clang/include/clang/Basic/AttrDocs.td | 12 ++++++++++++ clang/include/clang/Sema/SemaWasm.h | 1 + clang/lib/CodeGen/Targets/WebAssembly.cpp | 9 +++++++++ clang/lib/Sema/SemaDeclAttr.cpp | 3 +++ clang/lib/Sema/SemaWasm.cpp | 10 ++++++++++ .../WebAssembly/wasm-global-attribute.cpp | 16 ++++++++++++++++ .../llvm/Support}/WasmAddressSpaces.h | 14 ++++++-------- .../WebAssembly/Utils/WebAssemblyTypeUtilities.h | 2 +- .../Target/WebAssembly/WebAssemblyFastISel.cpp | 2 +- .../WebAssembly/WebAssemblyRefTypeMem2Local.cpp | 2 +- 11 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp rename llvm/{lib/Target/WebAssembly/Utils => include/llvm/Support}/WasmAddressSpaces.h (73%) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 61ef3fb612440..f11dcc77e8483 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2602,6 +2602,12 @@ def WebAssemblyImportName : InheritableAttr, let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; } +def WebAssemblyGlobal : InheritableAttr, TargetSpecificAttr<TargetWebAssembly> { + let Spellings = [Clang<"wasm_global">]; + let Documentation = [WebAssemblyGlobalDocs]; + let Subjects = SubjectList<[GlobalVar], ErrorDiag>; +} + def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 1bbaae8b21106..6140c827c24b0 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7337,6 +7337,18 @@ request a specific field name be used instead. }]; } +def WebAssemblyGlobalDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +Clang supports the `[[clang::wasm_global]]` attribute for the WebAssembly +target. This attribute declares that a variable is stored as a WebAssembly +global rather than in linear memory. + +WebAssembly globals can be imported or exported using the +`import_module`, `import_name`, and `export_name` attributes. + }]; +} + def ArtificialDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h index c70cda259029e..41245ef649e84 100644 --- a/clang/include/clang/Sema/SemaWasm.h +++ b/clang/include/clang/Sema/SemaWasm.h @@ -50,6 +50,7 @@ class SemaWasm : public SemaBase { void handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL); void handleWebAssemblyImportModuleAttr(Decl *D, const ParsedAttr &AL); void handleWebAssemblyImportNameAttr(Decl *D, const ParsedAttr &AL); + void handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL); }; } // namespace clang diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp index 8f6f58bfb807e..f51edfc620baa 100644 --- a/clang/lib/CodeGen/Targets/WebAssembly.cpp +++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp @@ -9,6 +9,7 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "llvm/Support/WasmAddressSpaces.h" using namespace clang; using namespace clang::CodeGen; @@ -55,6 +56,14 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo { std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); } + LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, + const VarDecl *D) const override { + if (D && D->hasAttr<WebAssemblyGlobalAttr>()) + return getLangASFromTargetAS( + llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); + return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D); + } + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override { TargetCodeGenInfo::setTargetAttributes(D, GV, CGM); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index eb4a8c2ab9ae0..6bc06c8f24b2b 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7750,6 +7750,9 @@ ProcessDeclAttribute(Sema &S, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_WebAssemblyImportName: S.Wasm().handleWebAssemblyImportNameAttr(D, AL); break; + case ParsedAttr::AT_WebAssemblyGlobal: + S.Wasm().handleWebAssemblyGlobalAttr(D, AL); + break; case ParsedAttr::AT_IBOutlet: S.ObjC().handleIBOutlet(D, AL); break; diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index cfc0a08a50e5a..d0fae91fa4727 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Attr.h" #include "clang/Sema/Sema.h" +#include "llvm/Support/WasmAddressSpaces.h" namespace clang { @@ -457,4 +458,13 @@ void SemaWasm::handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(UsedAttr::CreateImplicit(Context)); } +void SemaWasm::handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL) { + ASTContext &Context = getASTContext(); + auto *VD = cast<VarDecl>(D); + VD->setType(Context.getAddrSpaceQualType( + VD->getType(), getLangASFromTargetAS( + llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR))); + D->addAttr(::new (Context) WebAssemblyGlobalAttr(Context, AL)); +} + } // namespace clang diff --git a/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp b/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp new file mode 100644 index 0000000000000..e61056d9ba848 --- /dev/null +++ b/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s + +extern "C" { +int exported_g [[clang::wasm_global]] = 42; + +extern const int imported_g [[clang::wasm_global]] + __attribute__((import_module("env"), import_name("imported_g"))); + +int get_import(void) { return imported_g; } +} + +// CHECK: @exported_g = addrspace(1) global i32 42, align 4 +// CHECK: @imported_g = external addrspace(1) constant i32, align 4 #0 +// CHECK: define{{.*}} @get_import() +// CHECK: load i32, ptr addrspace(1) @imported_g +// CHECK: attributes #0 = { "wasm-import-module"="env" "wasm-import-name"="imported_g" } \ No newline at end of file diff --git a/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h b/llvm/include/llvm/Support/WasmAddressSpaces.h similarity index 73% rename from llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h rename to llvm/include/llvm/Support/WasmAddressSpaces.h index d2ab2c0f9e777..8738b4e88520d 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h +++ b/llvm/include/llvm/Support/WasmAddressSpaces.h @@ -1,4 +1,4 @@ -//===--- llvm/CodeGen/WasmAddressSpaces.h -----------------------*- C++ -*-===// +//===---------------- WasmAddressSpaces.h ----------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,22 +6,21 @@ // //===----------------------------------------------------------------------===// // -// Address Spaces for WebAssembly Type Handling +// Address spaces for WebAssembly IR and type handling. // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WASMADDRESSSPACES_H -#define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WASMADDRESSSPACES_H +#ifndef LLVM_SUPPORT_WASMADDRESSSPACES_H +#define LLVM_SUPPORT_WASMADDRESSSPACES_H namespace llvm { - namespace WebAssembly { enum WasmAddressSpace : unsigned { // Default address space, for pointers to linear memory (stack, heap, data). WASM_ADDRESS_SPACE_DEFAULT = 0, // A non-integral address space for pointers to named objects outside of - // linear memory: WebAssembly globals or WebAssembly locals. Loads and stores + // linear memory: WebAssembly globals or WebAssembly locals. Loads and stores // to these pointers are lowered to global.get / global.set or local.get / // local.set, as appropriate. WASM_ADDRESS_SPACE_VAR = 1 @@ -38,7 +37,6 @@ inline bool isValidAddressSpace(unsigned AS) { } } // namespace WebAssembly - } // namespace llvm -#endif // LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WASMADDRESSSPACES_H +#endif // LLVM_SUPPORT_WASMADDRESSSPACES_H \ No newline at end of file diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h index 47ba91df81161..72342393e410a 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h @@ -16,11 +16,11 @@ #define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYTYPEUTILITIES_H #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h" -#include "WasmAddressSpaces.h" #include "llvm/BinaryFormat/Wasm.h" #include "llvm/CodeGenTypes/MachineValueType.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/MC/MCSymbolWasm.h" +#include "llvm/Support/WasmAddressSpaces.h" namespace llvm { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index db03f5874234c..075330081b5ca 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -16,7 +16,6 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" -#include "Utils/WasmAddressSpaces.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblySubtarget.h" #include "WebAssemblyUtilities.h" @@ -33,6 +32,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/Support/WasmAddressSpaces.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsWebAssembly.h" #include "llvm/IR/Operator.h" diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp index 2c162308700af..6fdb04760514e 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp @@ -12,7 +12,6 @@ /// //===----------------------------------------------------------------------===// -#include "Utils/WasmAddressSpaces.h" #include "Utils/WebAssemblyTypeUtilities.h" #include "WebAssembly.h" #include "llvm/IR/Analysis.h" @@ -22,6 +21,7 @@ #include "llvm/IR/PassManager.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Pass.h" +#include "llvm/Support/WasmAddressSpaces.h" using namespace llvm; #define DEBUG_TYPE "wasm-ref-type-mem2local" >From 1e26388f0b91a97e7888ee16de9c2a929a34a0b7 Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Tue, 8 Sep 2026 15:56:09 +0800 Subject: [PATCH 2/8] Fix --- clang/lib/CodeGen/Targets/WebAssembly.cpp | 3 +-- clang/lib/Sema/SemaWasm.cpp | 4 ++-- llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp index f51edfc620baa..05f2391dc7e38 100644 --- a/clang/lib/CodeGen/Targets/WebAssembly.cpp +++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp @@ -59,8 +59,7 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo { LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const override { if (D && D->hasAttr<WebAssemblyGlobalAttr>()) - return getLangASFromTargetAS( - llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); + return getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D); } diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index d0fae91fa4727..42c8957585ea0 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -462,8 +462,8 @@ void SemaWasm::handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL) { ASTContext &Context = getASTContext(); auto *VD = cast<VarDecl>(D); VD->setType(Context.getAddrSpaceQualType( - VD->getType(), getLangASFromTargetAS( - llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR))); + VD->getType(), + getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR))); D->addAttr(::new (Context) WebAssemblyGlobalAttr(Context, AL)); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index 075330081b5ca..3eea32411a808 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -32,10 +32,10 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalVariable.h" -#include "llvm/Support/WasmAddressSpaces.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsWebAssembly.h" #include "llvm/IR/Operator.h" +#include "llvm/Support/WasmAddressSpaces.h" using namespace llvm; >From 7a185fc6415cb47b46b5514a3f6262d99f61ca7f Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Tue, 8 Sep 2026 17:14:35 +0800 Subject: [PATCH 3/8] Fix --- clang/test/Misc/pragma-attribute-supported-attributes-list.test | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 8f8c1aa3d3f9c..2285f3602b863 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -236,6 +236,7 @@ // CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: WeakRef (SubjectMatchRule_variable, SubjectMatchRule_function) // CHECK-NEXT: WebAssemblyExportName (SubjectMatchRule_function, SubjectMatchRule_variable_is_global) +// CHECK-NEXT: WebAssemblyGlobal (SubjectMatchRule_variable_is_global) // CHECK-NEXT: WebAssemblyImportModule (SubjectMatchRule_function, SubjectMatchRule_variable_is_global) // CHECK-NEXT: WebAssemblyImportName (SubjectMatchRule_function, SubjectMatchRule_variable_is_global) // CHECK-NEXT: WorkGroupSizeHint (SubjectMatchRule_function) >From 0da0bbc3d8a831df0cdc68164eddeb1319b9dcd1 Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Sat, 10 Oct 2026 15:33:52 +0800 Subject: [PATCH 4/8] Fix review --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/CodeGen/Targets/WebAssembly.cpp | 8 -------- clang/lib/Sema/SemaWasm.cpp | 4 ++++ clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp | 8 ++++++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 70f25c78a6f4a..f2cae681610fd 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -14023,6 +14023,8 @@ def err_builtin_pass_in_regs_non_class : Error< // WebAssembly reference type and table diagnostics. +def err_wasm_global_with_address_space : Error< + "'wasm_global' attribute cannot be used with an explicit address space">; def err_wasm_reference_pr : Error< "%select{pointer|reference}0 to WebAssembly reference type is not allowed">; def err_wasm_ca_reference : Error< diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp index 05f2391dc7e38..8f6f58bfb807e 100644 --- a/clang/lib/CodeGen/Targets/WebAssembly.cpp +++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp @@ -9,7 +9,6 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" #include "clang/Basic/DiagnosticFrontend.h" -#include "llvm/Support/WasmAddressSpaces.h" using namespace clang; using namespace clang::CodeGen; @@ -56,13 +55,6 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo { std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); } - LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, - const VarDecl *D) const override { - if (D && D->hasAttr<WebAssemblyGlobalAttr>()) - return getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); - return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D); - } - void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override { TargetCodeGenInfo::setTargetAttributes(D, GV, CGM); diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index 42c8957585ea0..67853b72c75c9 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -461,6 +461,10 @@ void SemaWasm::handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL) { void SemaWasm::handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL) { ASTContext &Context = getASTContext(); auto *VD = cast<VarDecl>(D); + if (VD->getType().getAddressSpace() != LangAS::Default) { + Diag(AL.getLoc(), diag::err_wasm_global_with_address_space); + return; + } VD->setType(Context.getAddrSpaceQualType( VD->getType(), getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR))); diff --git a/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp b/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp index e61056d9ba848..e83cfdd1855bf 100644 --- a/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp +++ b/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp @@ -1,7 +1,10 @@ // RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s extern "C" { -int exported_g [[clang::wasm_global]] = 42; +int exported_g [[clang::wasm_global]] = 0; + +extern int redeclared_g [[clang::wasm_global]]; +int redeclared_g = 0; extern const int imported_g [[clang::wasm_global]] __attribute__((import_module("env"), import_name("imported_g"))); @@ -9,7 +12,8 @@ extern const int imported_g [[clang::wasm_global]] int get_import(void) { return imported_g; } } -// CHECK: @exported_g = addrspace(1) global i32 42, align 4 +// CHECK: @exported_g = addrspace(1) global i32 0, align 4 +// CHECK: @redeclared_g = addrspace(1) global i32 0, align 4 // CHECK: @imported_g = external addrspace(1) constant i32, align 4 #0 // CHECK: define{{.*}} @get_import() // CHECK: load i32, ptr addrspace(1) @imported_g >From 79c6dd29a17b80464eccfec211fccad6d174176f Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Sat, 10 Oct 2026 15:41:02 +0800 Subject: [PATCH 5/8] fix review --- lld/test/wasm/global-symbol-type-mismatch.ll | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 lld/test/wasm/global-symbol-type-mismatch.ll diff --git a/lld/test/wasm/global-symbol-type-mismatch.ll b/lld/test/wasm/global-symbol-type-mismatch.ll new file mode 100644 index 0000000000000..a83c5e2bb43dc --- /dev/null +++ b/lld/test/wasm/global-symbol-type-mismatch.ll @@ -0,0 +1,29 @@ +; RUN: split-file %s %t +; RUN: llc -mtriple=wasm32-unknown-unknown -filetype=obj %t/use-global.ll -o %t/use-global.o +; RUN: llc -mtriple=wasm32-unknown-unknown -filetype=obj %t/define-global.ll -o %t/define-global.o +; RUN: llc -mtriple=wasm32-unknown-unknown -filetype=obj %t/define-data.ll -o %t/define-data.o +; RUN: wasm-ld --no-entry --export=read_global %t/use-global.o %t/define-global.o -o %t/matching.wasm +; RUN: not wasm-ld --no-entry --export=read_global %t/use-global.o %t/define-data.o -o %t/mismatch.wasm 2>&1 | FileCheck %s --check-prefix=GLOBAL-FIRST +; RUN: not wasm-ld --no-entry --export=read_global %t/define-data.o %t/use-global.o -o %t/mismatch.wasm 2>&1 | FileCheck %s --check-prefix=DATA-FIRST + +; GLOBAL-FIRST: error: symbol type mismatch: storage_global +; GLOBAL-FIRST-NEXT: >>> defined as WASM_SYMBOL_TYPE_GLOBAL in {{.*}}use-global.o +; GLOBAL-FIRST-NEXT: >>> defined as WASM_SYMBOL_TYPE_DATA in {{.*}}define-data.o + +; DATA-FIRST: error: symbol type mismatch: storage_global +; DATA-FIRST-NEXT: >>> defined as WASM_SYMBOL_TYPE_DATA in {{.*}}define-data.o +; DATA-FIRST-NEXT: >>> defined as WASM_SYMBOL_TYPE_GLOBAL in {{.*}}use-global.o + +;--- use-global.ll +@storage_global = external addrspace(1) global i32 + +define i32 @read_global() { + %value = load i32, ptr addrspace(1) @storage_global, align 4 + ret i32 %value +} + +;--- define-global.ll +@storage_global = addrspace(1) global i32 0, align 4 + +;--- define-data.ll +@storage_global = global i32 0, align 4 \ No newline at end of file >From 5e38db36580fd3e3d1b85022f1169260b087195c Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Sat, 10 Oct 2026 17:26:32 +0800 Subject: [PATCH 6/8] Add Sema Checker --- .../clang/Basic/DiagnosticSemaKinds.td | 10 +++ clang/include/clang/Sema/Initialization.h | 3 + clang/include/clang/Sema/SemaWasm.h | 1 + clang/lib/Sema/SemaDecl.cpp | 12 ++++ clang/lib/Sema/SemaExpr.cpp | 8 +++ clang/lib/Sema/SemaInit.cpp | 29 ++++++++ .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 6 ++ clang/lib/Sema/SemaWasm.cpp | 28 ++++++++ clang/test/Sema/attr-wasm.c | 33 +++++++++ clang/test/Sema/wasm-global-attribute.cpp | 72 +++++++++++++++++++ 10 files changed, 202 insertions(+) create mode 100644 clang/test/Sema/wasm-global-attribute.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index f2cae681610fd..1f23b53377231 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -14025,6 +14025,16 @@ def err_builtin_pass_in_regs_non_class : Error< // WebAssembly reference type and table diagnostics. def err_wasm_global_with_address_space : Error< "'wasm_global' attribute cannot be used with an explicit address space">; +def err_wasm_global_non_scalar : Error< + "'wasm_global' attribute requires a scalar type">; +def err_wasm_global_unsupported_type : Error< + "'wasm_global' attribute does not support type %0">; +def err_wasm_global_thread_local : Error< + "'wasm_global' attribute cannot be applied to a thread-local variable">; +def err_wasm_global_address_taken : Error< + "cannot take the address of a WebAssembly global">; +def err_wasm_global_reference_binding : Error< + "cannot bind a reference to a WebAssembly global">; def err_wasm_reference_pr : Error< "%select{pointer|reference}0 to WebAssembly reference type is not allowed">; def err_wasm_ca_reference : Error< diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index 2c2df1f03747b..4fd6aa1a8adbd 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -1107,6 +1107,9 @@ class InitializationSequence { /// Reference binding failed. FK_ReferenceInitFailed, + /// A reference cannot bind directly to a WebAssembly global. + FK_WasmGlobalReferenceBinding, + /// Implicit conversion failed. FK_ConversionFailed, diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h index 41245ef649e84..f0dce7e72a4b2 100644 --- a/clang/include/clang/Sema/SemaWasm.h +++ b/clang/include/clang/Sema/SemaWasm.h @@ -51,6 +51,7 @@ class SemaWasm : public SemaBase { void handleWebAssemblyImportModuleAttr(Decl *D, const ParsedAttr &AL); void handleWebAssemblyImportNameAttr(Decl *D, const ParsedAttr &AL); void handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL); + bool checkWebAssemblyGlobalType(VarDecl *VD); }; } // namespace clang diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1459b71326375..1a0d54d9d2038 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4792,6 +4792,10 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { mergeDeclAttributes(New, Old); + if (New->hasAttr<WebAssemblyGlobalAttr>() && + Wasm().checkWebAssemblyGlobalType(New)) + return New->setInvalidDecl(); + // Warn if an already-defined variable is made a weak_import in a subsequent // declaration if (New->hasAttr<WeakImportAttr>()) @@ -9023,6 +9027,14 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { if (T->isUndeducedType()) return; + if (NewVD->hasAttr<WebAssemblyGlobalAttr>()) { + if (Wasm().checkWebAssemblyGlobalType(NewVD)) { + NewVD->setInvalidDecl(); + return; + } + T = NewVD->getType(); + } + if (NewVD->hasAttrs()) CheckAlignasUnderalignment(NewVD); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ec74c3432b5cf..f1987188ae14d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -70,6 +70,7 @@ #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/TypeSize.h" +#include "llvm/Support/WasmAddressSpaces.h" #include <limits> #include <optional> @@ -15431,6 +15432,13 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { // Cannot take the address of WebAssembly references or tables. if (Context.getTargetInfo().getTriple().isWasm()) { QualType OpTy = op->getType(); + if (OpTy.getAddressSpace() == + getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR)) { + Diag(OpLoc, diag::err_wasm_global_address_taken) + << OrigOp.get()->getSourceRange(); + return QualType(); + } + if (OpTy.isWebAssemblyReferenceType()) { Diag(OpLoc, diag::err_wasm_ca_reference) << 1 << OrigOp.get()->getSourceRange(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index d2aa8691102aa..5acab7d2a057a 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -37,6 +37,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/WasmAddressSpaces.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -4029,6 +4030,7 @@ bool InitializationSequence::isAmbiguous() const { case FK_ReferenceAddrspaceMismatchTemporary: case FK_ReferenceInitDropsQualifiers: case FK_ReferenceInitFailed: + case FK_WasmGlobalReferenceBinding: case FK_ConversionFailed: case FK_ConversionFromPropertyFailed: case FK_TooManyInitsForScalar: @@ -5495,6 +5497,12 @@ static bool isNonReferenceableGLValue(Expr *E) { E->refersToMatrixElement(); } +static bool isWebAssemblyGlobalReference(Sema &S, const Expr *E) { + return S.Context.getTargetInfo().getTriple().isWasm() && E->isGLValue() && + E->getType().getAddressSpace() == + getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); +} + /// Reference initialization without resolving overloaded functions. /// /// We also can get here in C if we call a builtin which is declared as @@ -5537,6 +5545,12 @@ static void TryReferenceInitializationCore(Sema &S, (RefRelationship == Sema::Ref_Compatible || (Kind.isCStyleOrFunctionalCast() && RefRelationship == Sema::Ref_Related))) { + if (isWebAssemblyGlobalReference(S, Initializer)) { + Sequence.SetFailed( + InitializationSequence::FK_WasmGlobalReferenceBinding); + return; + } + // - is an lvalue (but is not a bit-field), and "cv1 T1" is // reference-compatible with "cv2 T2," or if (RefConv & (Sema::ReferenceConversions::DerivedToBase | @@ -5657,6 +5671,12 @@ static void TryReferenceInitializationCore(Sema &S, (InitCategory.isPRValue() && (S.getLangOpts().CPlusPlus17 || T2->isRecordType() || T2->isArrayType())))) { + if (isWebAssemblyGlobalReference(S, Initializer)) { + Sequence.SetFailed( + InitializationSequence::FK_WasmGlobalReferenceBinding); + return; + } + ExprValueKind ValueKind = InitCategory.isXValue() ? VK_XValue : VK_PRValue; if (InitCategory.isPRValue() && T2->isRecordType()) { // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the @@ -9279,6 +9299,11 @@ bool InitializationSequence::Diagnose(Sema &S, break; } + case FK_WasmGlobalReferenceBinding: + S.Diag(Kind.getLocation(), diag::err_wasm_global_reference_binding) + << Args[0]->getSourceRange(); + break; + case FK_ReferenceInitFailed: S.Diag(Kind.getLocation(), diag::err_reference_bind_failed) << DestType.getNonReferenceType() @@ -9652,6 +9677,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "reference with mismatching address space bound to temporary"; break; + case FK_WasmGlobalReferenceBinding: + OS << "reference bound to WebAssembly global"; + break; + case FK_ReferenceInitFailed: OS << "reference initialization failed"; break; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index b4881d0c6db5c..5de9a35ad7d5a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -6408,6 +6408,12 @@ VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( // Update the type of this variable template specialization. VarSpec->setType(TSI->getType()); + if (VarSpec->hasAttr<WebAssemblyGlobalAttr>()) { + CheckVariableDeclarationType(VarSpec); + if (VarSpec->isInvalidDecl()) + return nullptr; + } + // Convert the declaration into a definition now. VarSpec->setCompleteDefinition(); diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index 67853b72c75c9..0d81db0d6f99c 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -463,6 +463,12 @@ void SemaWasm::handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL) { auto *VD = cast<VarDecl>(D); if (VD->getType().getAddressSpace() != LangAS::Default) { Diag(AL.getLoc(), diag::err_wasm_global_with_address_space); + VD->setInvalidDecl(); + return; + } + if (VD->getTLSKind() != VarDecl::TLS_None) { + Diag(AL.getLoc(), diag::err_wasm_global_thread_local); + VD->setInvalidDecl(); return; } VD->setType(Context.getAddrSpaceQualType( @@ -471,4 +477,26 @@ void SemaWasm::handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(::new (Context) WebAssemblyGlobalAttr(Context, AL)); } +bool SemaWasm::checkWebAssemblyGlobalType(VarDecl *VD) { + QualType Type = VD->getType(); + SourceLocation Loc = VD->getAttr<WebAssemblyGlobalAttr>()->getLocation(); + LangAS GlobalAS = + getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); + if (Type.getAddressSpace() != GlobalAS) { + if (Type.getAddressSpace() != LangAS::Default) + return Diag(Loc, diag::err_wasm_global_with_address_space); + VD->setType(getASTContext().getAddrSpaceQualType(Type, GlobalAS)); + } + + if (Type->isDependentType() || Type->isUndeducedType()) + return false; + + if (!Type->isScalarType()) + return Diag(Loc, diag::err_wasm_global_non_scalar); + if (Type->isAnyComplexType() || Type->isMemberPointerType() || + getASTContext().getTypeSize(Type) > 64) + return Diag(Loc, diag::err_wasm_global_unsupported_type) << Type; + return false; +} + } // namespace clang diff --git a/clang/test/Sema/attr-wasm.c b/clang/test/Sema/attr-wasm.c index 23cb212d6acc9..8f29aa561b2bb 100644 --- a/clang/test/Sema/attr-wasm.c +++ b/clang/test/Sema/attr-wasm.c @@ -49,3 +49,36 @@ extern int module_z_var __attribute__((import_module("bar"))); //expected-warnin // Explicit 'used' on non-definition still warns, while 'export_name' (implicit 'used') does not extern int explicit_used_var __attribute__((used)); //expected-warning {{'used' attribute ignored on a non-definition declaration}} +struct WasmGlobalRecord { + int value; +}; + +extern struct WasmGlobalRecord wasm_global_record + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute requires a scalar type}} +extern int wasm_global_array[2] + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute requires a scalar type}} +extern int wasm_global_value __attribute__((wasm_global)); +extern int wasm_global_value; +int wasm_global_value = 0; +extern int *wasm_global_pointer __attribute__((wasm_global)); +extern long long wasm_global_integer __attribute__((wasm_global)); +extern unsigned _BitInt(64) wasm_global_bitint __attribute__((wasm_global)); +extern double wasm_global_double __attribute__((wasm_global)); +extern _Complex double wasm_global_complex + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute does not support type}} +extern long double wasm_global_long_double + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute does not support type}} +extern unsigned _BitInt(65) wasm_global_wide_bitint + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute does not support type}} +extern int __attribute__((address_space(1))) wasm_global_address_space + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute cannot be used with an explicit address space}} + +_Thread_local int wasm_global_c_tls + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute cannot be applied to a thread-local variable}} +__thread int wasm_global_gnu_tls + __attribute__((wasm_global)); // expected-error {{'wasm_global' attribute cannot be applied to a thread-local variable}} + +void wasm_global_address_test(void) { + int *pointer = &wasm_global_value; // expected-error {{cannot take the address of a WebAssembly global}} +} + diff --git a/clang/test/Sema/wasm-global-attribute.cpp b/clang/test/Sema/wasm-global-attribute.cpp new file mode 100644 index 0000000000000..987b4fe1de94d --- /dev/null +++ b/clang/test/Sema/wasm-global-attribute.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -std=c++17 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple wasm64-unknown-unknown-wasm -std=c++17 -fsyntax-only -verify %s + +int wasm_global_scalar [[clang::wasm_global]]; +int wasm_global_second [[clang::wasm_global]]; +int *wasm_global_pointer [[clang::wasm_global]]; +bool wasm_global_bool [[clang::wasm_global]]; +long long wasm_global_integer [[clang::wasm_global]]; +unsigned _BitInt(64) wasm_global_bitint [[clang::wasm_global]]; +float wasm_global_float [[clang::wasm_global]]; +double wasm_global_double [[clang::wasm_global]]; +enum class ScalarEnum { Zero }; +ScalarEnum wasm_global_enum [[clang::wasm_global]]; +thread_local int wasm_global_tls [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute cannot be applied to a thread-local variable}} +__thread int wasm_global_gnu_tls [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute cannot be applied to a thread-local variable}} + +struct Record { int value; }; +using MemberFunction = void (Record::*)(); +using MemberData = int Record::*; +_Complex double wasm_global_complex [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute does not support type}} +MemberFunction wasm_global_member_function [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute does not support type}} +MemberData wasm_global_member_data [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute does not support type}} +long double wasm_global_long_double [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute does not support type}} +unsigned _BitInt(65) wasm_global_wide_bitint [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute does not support type}} +__int128 wasm_global_int128 [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute does not support type}} + +auto wasm_global_auto [[clang::wasm_global]] = 0; +auto wasm_global_auto_pointer [[clang::wasm_global]] = static_cast<int *>(nullptr); +decltype(auto) wasm_global_decltype_auto [[clang::wasm_global]] = 0; +auto wasm_global_auto_record [[clang::wasm_global]] = Record{}; // expected-error {{'wasm_global' attribute requires a scalar type}} +auto wasm_global_auto_wide [[clang::wasm_global]] = (__int128)0; // expected-error {{'wasm_global' attribute does not support type}} + +template <class T> +T wasm_global_template [[clang::wasm_global]] = T{}; // expected-error {{'wasm_global' attribute requires a scalar type}} expected-error {{'wasm_global' attribute does not support type}} +int read_wasm_global_template() { return wasm_global_template<int>; } +Record instantiate_record = wasm_global_template<Record>; // expected-note {{in instantiation of variable template specialization}} +auto instantiate_wide = wasm_global_template<__int128>; // expected-note {{in instantiation of variable template specialization}} + +template <class T> +struct ClassGlobal { + static T value [[clang::wasm_global]]; // expected-error {{'wasm_global' attribute requires a scalar type}} +}; +int read_class_global() { return ClassGlobal<int>::value; } +Record instantiate_class_record = ClassGlobal<Record>::value; // expected-note {{in instantiation of template class}} + +using WasmInt = int __attribute__((address_space(1))); + +void wasm_global_address_test(bool condition) { + auto pointer = &wasm_global_scalar; // expected-error {{cannot take the address of a WebAssembly global}} + auto builtin_pointer = __builtin_addressof(wasm_global_scalar); // expected-error {{cannot take the address of a WebAssembly global}} + auto comma_pointer = &((void)0, wasm_global_scalar); // expected-error {{cannot take the address of a WebAssembly global}} + auto conditional_pointer = &(condition ? wasm_global_scalar : wasm_global_second); // expected-error {{cannot take the address of a WebAssembly global}} + auto conditional_builtin_pointer = __builtin_addressof(condition ? wasm_global_scalar : wasm_global_second); // expected-error {{cannot take the address of a WebAssembly global}} + auto assignment_pointer = &(wasm_global_scalar = 0); // expected-error {{cannot take the address of a WebAssembly global}} + auto increment_pointer = &++wasm_global_scalar; // expected-error {{cannot take the address of a WebAssembly global}} + WasmInt &reference = wasm_global_scalar; // expected-error {{cannot bind a reference to a WebAssembly global}} + WasmInt &comma_reference = ((void)0, wasm_global_scalar); // expected-error {{cannot bind a reference to a WebAssembly global}} + WasmInt &conditional_reference = condition ? wasm_global_scalar : wasm_global_second; // expected-error {{cannot bind a reference to a WebAssembly global}} + WasmInt &assignment_reference = (wasm_global_scalar = 0); // expected-error {{cannot bind a reference to a WebAssembly global}} + WasmInt &increment_reference = ++wasm_global_scalar; // expected-error {{cannot bind a reference to a WebAssembly global}} + auto &&xvalue_reference = static_cast<WasmInt &&>(wasm_global_scalar); // expected-error {{cannot bind a reference to a WebAssembly global}} + + const int &copied_reference = static_cast<int>(wasm_global_scalar); + const double &converted_reference = static_cast<double>(wasm_global_scalar); + auto &&value_reference = +wasm_global_scalar; + auto copied_pointer_value = wasm_global_pointer; + auto pointee_pointer = &*wasm_global_pointer; + auto &pointee_reference = *wasm_global_pointer; + int ordinary; + auto ordinary_pointer = &ordinary; + auto &ordinary_reference = ordinary; +} \ No newline at end of file >From 06c25130ad7179ac2a9d3e7251b8b5ed032fae7d Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Sat, 10 Oct 2026 17:44:37 +0800 Subject: [PATCH 7/8] Fix --- clang/lib/Sema/SemaInit.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 5acab7d2a057a..5f732cad16292 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5672,8 +5672,7 @@ static void TryReferenceInitializationCore(Sema &S, (S.getLangOpts().CPlusPlus17 || T2->isRecordType() || T2->isArrayType())))) { if (isWebAssemblyGlobalReference(S, Initializer)) { - Sequence.SetFailed( - InitializationSequence::FK_WasmGlobalReferenceBinding); + Sequence.SetFailed(InitializationSequence::FK_WasmGlobalReferenceBinding); return; } >From 6bbd14c4b35c3ac0356fca248357d63b2f02785b Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Sat, 10 Oct 2026 18:32:58 +0800 Subject: [PATCH 8/8] Fix --- clang/lib/Sema/SemaExpr.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f1987188ae14d..cb91e534c53ed 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -15432,13 +15432,6 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { // Cannot take the address of WebAssembly references or tables. if (Context.getTargetInfo().getTriple().isWasm()) { QualType OpTy = op->getType(); - if (OpTy.getAddressSpace() == - getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR)) { - Diag(OpLoc, diag::err_wasm_global_address_taken) - << OrigOp.get()->getSourceRange(); - return QualType(); - } - if (OpTy.isWebAssemblyReferenceType()) { Diag(OpLoc, diag::err_wasm_ca_reference) << 1 << OrigOp.get()->getSourceRange(); @@ -15449,6 +15442,12 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { << 1 << OrigOp.get()->getSourceRange(); return QualType(); } + if (OpTy.getAddressSpace() == + getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR)) { + Diag(OpLoc, diag::err_wasm_global_address_taken) + << OrigOp.get()->getSourceRange(); + return QualType(); + } } CheckAddressOfPackedMember(op); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
