Skip to content

Commit 2fc32bc

Browse files
authored
Test with LLVM 22 in CI, fix a setjmp/longjmp issue (WebAssembly#772)
This commit adds a new CI builder for LLVM 22, distinct from preexisting builders using LLVM 20. This notably exposes a bug where setjmp/longjmp needed a fix because the method of definition of `__c_setjmp`, the tag used, changed in LLVM 22. > **Note**: this is temporarily built on WebAssembly#770 and WebAssembly#771
1 parent 1e644fd commit 2fc32bc

4 files changed

Lines changed: 35 additions & 4 deletions

File tree

.github/actions/setup/action.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,22 @@ runs:
5151
echo "NM=$CLANG_DIR/llvm-nm" >> $GITHUB_ENV
5252
if: runner.os == 'macOS'
5353

54-
# Note that this uses apt-based packages for installing Clang/tools to
55-
# ensure that all various dependencies are also installed. Binaries from
56-
# llvm-project depend on libtinfo.so and TBH I don't know what that is.
57-
# Using apt-get should basically serve the same purpose though.
54+
# Use apt repositories to install various clang versions on Linux as those
55+
# generally work the best and are more available than per-release downloads
56+
# of LLVM. Note that apt.llvm.org may be used for new enough versions of
57+
# clang which aren't in Ubuntu 24.04.
5858
- name: Install LLVM tools (Linux)
5959
shell: bash
6060
run: |
6161
set -ex
6262
v=${{ inputs.clang_version }}
63+
# For LLVM versions 21+ install from apt.llvm.org because the ubuntu
64+
# 24.04 repositories don't have these binaries.
65+
if [ $v -ge 21 ]; then
66+
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
67+
rel=$(lsb_release -cs)
68+
sudo apt-add-repository "deb http://apt.llvm.org/$rel/ llvm-toolchain-$rel-$v main"
69+
fi
6370
sudo apt-get update
6471
sudo apt-get install -y clang-$v clang-tools-$v lld-$v
6572
echo "CC=clang-$v" >> $GITHUB_ENV

.github/workflows/main.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ jobs:
162162
test: true
163163
args: -DTARGET_TRIPLE=wasm32-wasip2
164164

165+
- name: Test LLVM 22
166+
os: ubuntu-24.04
167+
clang_version: 22
168+
test: true
169+
args: -DTARGET_TRIPLE=wasm32-wasip2
165170
steps:
166171
- uses: actions/checkout@v6
167172
with:

cmake/scripts/run-check-symbols.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ foreach(symbol IN LISTS final_undefined_symbols)
7878
if(NOT symbol MATCHES "^__mul" AND
7979
NOT symbol STREQUAL "__memory_base" AND
8080
NOT symbol STREQUAL "__indirect_function_table" AND
81+
NOT symbol STREQUAL "__wasm_first_page_end" AND
8182
NOT symbol STREQUAL "__tls_base")
8283
file(APPEND ${out_undefined_symbols} "${symbol}\n")
8384
endif()

libc-top-half/musl/src/setjmp/wasm32/rt.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,21 @@ __wasm_longjmp(void *env, int val)
8181
arg->val = val;
8282
__builtin_wasm_throw(1, arg); /* 1 == C_LONGJMP */
8383
}
84+
85+
// The `__builtin_wasm_throw` invocation above will reference this symbol which
86+
// refers to a WebAssembly tag. The tag can't be defined in C but we can define
87+
// it with inline assembly, so do so here.
88+
//
89+
// Note that the means of defining this symbol changed historically, so this
90+
// is only done on LLVM 22+ where it's required.
91+
#if __clang_major__ >= 22
92+
__asm__(".globl __c_longjmp\n"
93+
#if defined(__wasm32__)
94+
".tagtype __c_longjmp i32\n"
95+
#elif defined(__wasm64__)
96+
".tagtype __c_longjmp i64\n"
97+
#else
98+
#error "Unsupported Wasm architecture"
99+
#endif
100+
"__c_longjmp:\n");
101+
#endif

0 commit comments

Comments
 (0)