Skip to content

Get Clang's PCH fixes merged (bounty: $1000) #446

@jeaye

Description

@jeaye

Overview

We have an open PR waiting to be merged into LLVM. The PR fixes an issue with PCHs in jank. The PR is here: llvm/llvm-project#94166

However, I've done work to the PR which hasn't been merged. That can be found here: https://github.com/jank-lang/llvm-project/tree/jeaye/original-fix-pch

The test within my branch passes, but when we try to catch this branch up with the latest LLVM, the test no longer passes. I have a branch with all of this merged into the latest LLVM available here: https://github.com/jank-lang/llvm-project/tree/jeaye/fix-pch

The culprit

I have bisected the LLVM commits to find the commit which introduced the breakage in our test. That commit is here: llvm/llvm-project@a72d7eea54134

There are some big changes to the IncrementalParser constructor, which is what I believe to be the issue.

Building Clang

To debug this, you should have two clones of Clang.

  1. jeaye/original-fix-pch: The original, working code
  2. jeaye/fix-pch: The original patched merged on top of LLVM 22

To build both of them, just use this script (build.sh). It assumes you have python and ccache and ninja installed.

#!/usr/bin/env bash

set -euo pipefail

mkdir -p "build"
cd "build"

cmake -DCMAKE_BUILD_TYPE=Debug \
      -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
      -DLLVM_ENABLE_RUNTIMES=all \
      -DLLVM_BUILD_LLVM_DYLIB=ON \
      -DLLVM_LINK_LLVM_DYLIB=ON \
      -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt" \
      -DLLVM_TARGETS_TO_BUILD="host" \
      -DLLVM_ENABLE_EH=OFF \
      -DLLVM_ENABLE_RTTI=ON \
      -DLLVM_INCLUDE_BENCHMARKS=OFF \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DLLVM_INCLUDE_EXAMPLES=OFF \
      -DLLVM_INCLUDE_TESTS=ON \
      -DLLVM_ENABLE_ZSTD=OFF \
      -DLLVM_BUILD_OCAML_BINDINGS=OFF \
      -DLLVM_ENABLE_OCAMLDOC=OFF \
      -G "Ninja" \
      ../llvm

ninja clang clang-repl FileCheck -j30

The test (and the PCH problem)

The original PR was written to solve a problem with symbols defined in a PCH not being able to JIT link. The test for this is straightforward.

  1. Define a symbol in a header file
  2. Compiler the header to a PCH
  3. Load the PCH into Clang's JIT runtime
  4. Try to reference the symbol

If step 4 passes, we win. In my jeaye/original-fix-pch branch, it passes. In my jeaye/fix-pch branch, it fails. Here are the steps to reproduce this test easily.

The header file

Create a build/include.hpp with this for contents:

int f_pch() { return 5; }

The script

Create a script called test.sh with this for contents:

#!/usr/bin/env bash

set -euo pipefail

cd build
./bin/clang -fmax-type-align=16 -Xclang -pic-level -Xclang 2 -Xclang -fdeprecated-macro -fno-stack-protector -Xclang -fwrapv -fPIC -Xclang -fblocks -Xclang -fskip-odr-check-in-gmf -fexceptions -fcxx-exceptions -fgnuc-version=0 -target x86_64-unknown-linux-gnu -Xclang -fblocks -Xclang -fmax-type-align=8 -Xclang -fincremental-extensions -Xclang -emit-pch -x c++-header -o include.pch include.hpp

./bin/clang-repl -Xcc -fgnuc-version=0 -Xcc -fno-stack-protector -Xcc -fwrapv -Xcc -fPIC -Xcc -fblocks -Xcc -fskip-odr-check-in-gmf -Xcc -fmax-type-align=8 -Xcc -include-pch -Xcc include.pch "f_pch();"

echo "The test passes!"

When you invoke this with Clang/LLVM built from jeaye/original-fix-pch, it should pass.

NOTE: If you're not building on x86_64 Linux, you will want to change the -target flag in the script to match your own target triple.

Recommended steps

We need to figure out how the problem commit (llvm/llvm-project@a72d7eea54134) broke our test case. One way would be to read through the code, but another way would be to step through clang-repl with both builds at the same time, to spot differences. I suspect a combination of the two will be needed.

Support

For support, join the Compiler Research Group discord here: https://discord.gg/8AaAnfc8
Post to the #clang-repl channel and ping me and @vvassilev.

Bounty

I will pay $1000 out of pocket to whoever provides a fix for this, which then leads to this PR being merged into upstream LLVM. This would allow jank to start using packaged LLVM once the next version (22) is released, which would greatly simplify our packaging and distribution. If multiple people have provide fixes, which is unlikely, I will use my discretion to determine who gets the bounty. Payout method is flexible, but Github sponsors is preferred.

If you want to tackle this, leave a comment on this PR so that others can have an idea of how many folks are interested. This would help them gauge whether or not to take a look, since we're not assigning this to one person.

Metadata

Metadata

Assignees

No one assigned

    Labels

    category:clangClang usage for parsing, compiling, formatting, linking, etc.help wanted

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions