From 3c7a10df9062b7fe0f69f2b769fc993f9fde13be Mon Sep 17 00:00:00 2001 From: Hugo Date: Sun, 1 Nov 2026 04:12:32 +0100 Subject: [PATCH 1/7] build(cmake): require LLVM 20, since LLVM 19 no longer compiles the analyzer Since 33fe390, src/analysis/ownership/ResourceFactCollector.cpp reads the callee's `captures` attribute through llvm::CaptureInfo, llvm::CaptureComponents, llvm::capturesNothing and llvm::Argument::getAttributes(), which LLVM 20 introduced. CMake still accepted LLVM 19, so a build with it passed configuration and then failed to compile that file. Configuration now stops with the error of check_llvm_version instead. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8539319..9c8c1b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ include(CheckLLVMVersion OPTIONAL) include(CheckCXXCompilerFlag) if(COMMAND check_llvm_version) - set(LLVM_MIN_REQUIRED_VERSION "19" CACHE STRING "Minimum required LLVM version") + set(LLVM_MIN_REQUIRED_VERSION "20" CACHE STRING "Minimum required LLVM version") check_llvm_version(${LLVM_MIN_REQUIRED_VERSION}) else() message(WARNING "check_llvm_version() not available, skipping LLVM version check") From f15723928355dc28f5be10860f40da4f73f21c8d Mon Sep 17 00:00:00 2001 From: Hugo Date: Sun, 1 Nov 2026 04:12:32 +0100 Subject: [PATCH 2/7] build(scripts): stop looking for Homebrew llvm@19 and llvm@18 CMake now requires LLVM 20, so the script would only hand it a version that configuration rejects. --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 8fa04c3..371a052 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -219,7 +219,7 @@ detect_from_brew() { local formula local prefix - for formula in llvm llvm@20 llvm@19 llvm@18; do + for formula in llvm llvm@20; do prefix="$(brew --prefix "$formula" 2>/dev/null || true)" if [ -n "$prefix" ] && [ -d "$prefix" ]; then if [ -z "$LLVM_DIR" ] && [ -d "$prefix/lib/cmake/llvm" ]; then From 09755acf6987f6f45a76ca51e4facb807ec0cc5d Mon Sep 17 00:00:00 2001 From: Hugo Date: Sun, 1 Nov 2026 04:12:32 +0100 Subject: [PATCH 3/7] build(scripts): look for Homebrew llvm@20 before the unversioned llvm The script takes the first formula it finds, and it tried `llvm` first. Homebrew's `llvm` formula is LLVM 23.1 as of this change, while the analyzer builds with LLVM 20 only (LLVM 21 is tracked in #259), so with both formulas installed the script picked the wrong one. `llvm` stays as the fallback. --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 371a052..fd1acfa 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -219,7 +219,7 @@ detect_from_brew() { local formula local prefix - for formula in llvm llvm@20; do + for formula in llvm@20 llvm; do prefix="$(brew --prefix "$formula" 2>/dev/null || true)" if [ -n "$prefix" ] && [ -d "$prefix" ]; then if [ -z "$LLVM_DIR" ] && [ -d "$prefix/lib/cmake/llvm" ]; then From aef144bc6c9f0283ea3bd71fe84c55c614ea201d Mon Sep 17 00:00:00 2001 From: Hugo Date: Sun, 1 Nov 2026 04:12:32 +0100 Subject: [PATCH 4/7] docs(contributing): require LLVM/Clang 20 The prerequisites still listed LLVM 19 as the minimum, with 20 recommended. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57d7aba..60f80e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ This document defines the expected workflow for code, tests, and pull requests. Prerequisites: - CMake `>= 3.16` -- LLVM/Clang `>= 19` (20 recommended) +- LLVM/Clang 20 - A C++20 compiler Build: From c97b49c2e43c2ee3dbd31e57198bc9a3905b102f Mon Sep 17 00:00:00 2001 From: Hugo Date: Sun, 1 Nov 2026 04:12:32 +0100 Subject: [PATCH 5/7] docs(readme): state that the build needs LLVM and Clang 20 The build section named no LLVM version. It now names the one the analyzer builds with, and how to install it on macOS and Ubuntu. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 0f0d00b..420cbbd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ #### BUILD (macOS/Linux) +The analyzer builds with LLVM and Clang 20 only. On macOS, install them with +`brew install llvm@20`, not `llvm`, which is a later version. On Ubuntu, install +`llvm-20-dev`, `libclang-20-dev` and `clang-20` from apt.llvm.org. + ```zsh ./build.sh ``` From aa648dc1c0e7ad7db7b9ef35aebfa0248dc940cf Mon Sep 17 00:00:00 2001 From: Hugo Date: Sun, 1 Nov 2026 04:12:32 +0100 Subject: [PATCH 6/7] docs(changelog): announce that building and the action require LLVM 20 The second entry covers the action change of #257, which added no changelog entry. --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad32fea..ac39bb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ Notable changes are grouped by release. See [all releases](https://github.com/Co ## Unreleased +- Building requires LLVM 20. CMake rejects an older LLVM when it configures the build, where + LLVM 19 passed that check and then failed to compile. On macOS, `scripts/build.sh` looks for + Homebrew `llvm@20` before `llvm`, a later version, and no longer for `llvm@19` or `llvm@18`. +- The GitHub Action accepts `llvm-version: 20` only. On a runner for which apt.llvm.org + publishes no LLVM 20 packages, such as `ubuntu-26.04`, it stops with an error before + installing LLVM (#255). - StackBufferOverflow and MultipleStoresToStackBuffer resolve each pointer variable to its stack array once per function, by strongly connected components: pointer variables assigned from one another no longer make the analysis walk every path between them, From 1db000677d07e1250fbbf406fdfca7a10b4f97c3 Mon Sep 17 00:00:00 2001 From: Hugo Date: Sun, 1 Nov 2026 19:51:01 +0100 Subject: [PATCH 7/7] build(cmake): apply the LLVM 20 floor to build directories configured before LLVM_MIN_REQUIRED_VERSION was a cache variable, and set(CACHE) keeps a value that the cache already holds. A build directory configured before the floor moved to 20 kept 19, so running ./build.sh again after an update still accepted LLVM 19, and the build failed during compilation. check_llvm_version now receives 20 directly, on every configuration. Nothing in the repository set the variable; a command line that still passes it gets CMake's warning about unused variables. --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c8c1b5..516ff4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,7 @@ include(CheckLLVMVersion OPTIONAL) include(CheckCXXCompilerFlag) if(COMMAND check_llvm_version) - set(LLVM_MIN_REQUIRED_VERSION "20" CACHE STRING "Minimum required LLVM version") - check_llvm_version(${LLVM_MIN_REQUIRED_VERSION}) + check_llvm_version(20) else() message(WARNING "check_llvm_version() not available, skipping LLVM version check") endif()