diff options
| author | Heejin Ahn <aheejin@gmail.com> | 2026-02-12 13:33:18 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-12 13:33:18 -0800 |
| commit | c1e90fa663ca46c70d079503b83340d5e38105a4 (patch) | |
| tree | ed1a037707ab83f88af5d384c496706fe1ebe2df /llvm/lib | |
| parent | a8be67e6f3da18b70961a72c56a3f802b4ab4da9 (diff) | |
| download | llvm-main.zip llvm-main.tar.gz llvm-main.tar.bz2 | |
This checks every user function of `setjmp` or `longjmp` and if any of
them does not have `+exception-handling` target feature, errors out.
Hopefully this gives a clearer error message to the users in case they
do not provide consistent SjLj flags at compile time vs. link time.
Closes #178135 and closes
https://github.com/emscripten-core/emscripten/issues/26165.
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp index c3990d1..ba81537 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -482,6 +482,14 @@ static Value *getAddrSizeInt(Module *M, uint64_t C) { return IRB.getIntN(M->getDataLayout().getPointerSizeInBits(), C); } +// Returns true if the function has "target-features"="+exception-handling" +// attribute. +static bool hasEHTargetFeatureAttr(const Function &F) { + Attribute FeaturesAttr = F.getFnAttribute("target-features"); + return FeaturesAttr.isValid() && + FeaturesAttr.getValueAsString().contains("+exception-handling"); +} + // Returns __cxa_find_matching_catch_N function, where N = NumClauses + 2. // This is because a landingpad instruction contains two more arguments, a // personality function and a cleanup bit, and __cxa_find_matching_catch_N @@ -1004,6 +1012,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) { // Function registration and data pre-gathering for setjmp/longjmp handling if (DoSjLj) { assert(EnableEmSjLj || EnableWasmSjLj); + if (EnableEmSjLj) { // Register emscripten_longjmp function FunctionType *FTy = FunctionType::get( @@ -1019,6 +1028,22 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) { WasmLongjmpF->addFnAttr(Attribute::NoReturn); } + if (EnableWasmSjLj) { + for (auto *SjLjF : {SetjmpF, LongjmpF}) { + if (SjLjF) { + for (User *U : SjLjF->users()) { + if (auto *CI = dyn_cast<CallInst>(U)) { + auto &F = *CI->getFunction(); + if (!hasEHTargetFeatureAttr(F)) + report_fatal_error("Function " + F.getName() + + " is using setjmp/longjmp but does not have " + "+exception-handling target feature"); + } + } + } + } + } + if (SetjmpF) { Type *Int8PtrTy = IRB.getPtrTy(); Type *Int32PtrTy = IRB.getPtrTy(); |
