maskRootdir() built its strip-regex from this process's os.tmpdir(), so
it only masked paths whose root matched the current tmpdir. That is
fragile in two real cases:
- The path being masked is recorded when the compile runs and need not
share the masking process's tmpdir. Snapshots/fixtures that freeze
/tmp/... paths only mask on hosts where os.tmpdir() is /tmp (they fail
where it is e.g. /usr/tmp).
- On macOS os.tmpdir() returns /var/folders/... while real temp paths
often resolve via /private/var/folders/..., so masking silently missed.
- A configured temp root (temp dirs created outside os.tmpdir()) was
never matched at all.
Key the regex off the distinctive ce_temp_prefix marker instead,
matching whatever path segments precede it. This is tmpdir-independent
and unifies the Windows and non-Windows branches into one rule (also
masking embedded temp paths like `-I/tmp/.../include` on Windows, which
the old anchored branch missed).
Adds unit tests for maskRootdir (previously untested) covering /tmp,
/usr/tmp, macOS /private/var, Windows, the -I include case, and non-temp
paths left untouched.
<!-- THIS COMMENT IS INVISIBLE IN THE FINAL PR, BUT FEEL FREE TO REMOVE
IT
Thanks for taking the time to improve CE. We really appreciate it.
Before opening the PR, please make sure that the tests & linter pass
their checks,
by running `make check`.
In the best case scenario, you are also adding tests to back up your
changes,
but don't sweat it if you don't. We can discuss them at a later date.
Feel free to append your name to the CONTRIBUTORS.md file
Thanks again, we really appreciate this!
-->
---------
Co-authored-by: Matt Godbolt <mattgodbolt@hudson-trading.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This patch adds support for viewing the abstract syntax tree (AST) of
Python source code in Compiler Explorer, matching the existing AST
viewer feature for C/C++ (Clang AST).
- This patch adds a helper script `ast_dump.py` that parses and dumps
the AST for a Python source code file. `python -m ast` should also work,
but it's not available in old versions of Python.
- This patch adds an AST parser for Python which mimics the structure of
the C/C++ AST parser. It also updates the Python compiler to enable AST
output.
- All existing and new tests pass.
Assisted-by: GitHub Copilot / DeepSeek v4 Flash
Assisted-by: GitHub Copilot / DeepSeek v4 Pro
<!-- THIS COMMENT IS INVISIBLE IN THE FINAL PR, BUT FEEL FREE TO REMOVE
IT
Thanks for taking the time to improve CE. We really appreciate it.
Before opening the PR, please make sure that the tests & linter pass
their checks,
by running `make check`.
In the best case scenario, you are also adding tests to back up your
changes,
but don't sweat it if you don't. We can discuss them at a later date.
Feel free to append your name to the CONTRIBUTORS.md file
Thanks again, we really appreciate this!
-->
Co-authored-by: Matt Godbolt <matt@godbolt.org>
Bumps [soupsieve](https://github.com/facelessuser/soupsieve) from 2.8.3
to 2.8.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facelessuser/soupsieve/releases">soupsieve's
releases</a>.</em></p>
<blockquote>
<h2>2.8.4</h2>
<ul>
<li><strong>FIX</strong>: Fix another inefficient attribute pattern (<a
href="https://github.com/mauriceng98"><code>@mauriceng98</code></a>).</li>
<li><strong>FIX</strong>: Limit total number of selectors processed in a
pattern to prevent massive selector requests (<a
href="https://github.com/mauriceng98"><code>@mauriceng98</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="28108ab805"><code>28108ab</code></a>
Limit excessive selectors</li>
<li><a
href="ef188721d6"><code>ef18872</code></a>
Fix test for Windows</li>
<li><a
href="eb43976187"><code>eb43976</code></a>
Merge commit from fork</li>
<li><a
href="3a661b23b2"><code>3a661b2</code></a>
Fix typo in pseudo-classes.md (<a
href="https://redirect.github.com/facelessuser/soupsieve/issues/294">#294</a>)</li>
<li><a
href="0cb533d83b"><code>0cb533d</code></a>
Update hatchling version requirement in pyproject.toml (<a
href="https://redirect.github.com/facelessuser/soupsieve/issues/290">#290</a>)</li>
<li>See full diff in <a
href="https://github.com/facelessuser/soupsieve/compare/2.8.3...2.8.4">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/compiler-explorer/compiler-explorer/network/alerts).
</details>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
*(I'm Molty, an AI assistant acting on behalf of @mattgodbolt)*
Adds CE properties entries so the new compiler versions installed in
compiler-explorer/infra#2230 appear in the UI. Companion to
**compiler-explorer/infra#2230**.
Follows existing patterns exactly — no existing entries removed, no
existing IDs changed. `defaultCompiler` for each affected group is
bumped to the newest added version.
## Versions added
| Language | File | New versions | IDs |
|---|---|---|---|
| Crystal | `crystal.amazon.properties` | 1.20.3 | `crystal1203` |
| Nim | `nim.amazon.properties` | 2.0.16, 2.2.10 | `nim20016`, `nim2210`
|
| Pony | `pony.amazon.properties` | 0.52.5 → 0.67.0 (16 releases) |
`p0525`…`p0670` |
| TinyGo | `go.amazon.properties` | 0.41.1 | `tinygo0411` |
| Rakudo | `raku.amazon.properties` | 2025.06.1, 2025.08, 2025.10–12,
2026.01–06 | `rakudo-moar-2026-06-01` etc. |
| Wasmtime | `wasm.amazon.properties` | 46.0.1 | `wasmtime4601` |
| Sway | `sway.amazon.properties` | 0.69.6, 0.70.3, 0.71.2 |
`swayv0696`, `swayv0703`, `swayv0712` |
| Sail | `sail.amazon.properties` | 0.19.1, 0.20.2 | `sail_0_19_1`,
`sail_0_20_2` |
Note: the Rakudo 2025.06 release is the `2025.06.1-01` point release,
added as `rakudo-moar-2025-06-1-01` (name *Rakudo 2025.06.1 MoarVM*) to
mirror infra, following the existing `2021-02-1-01` special-case
pattern.
## Not included: Kotlin/Native
infra#2230 also installs Kotlin/Native 2.3.0–2.4.0, but there is
currently **no `kotlin-native` language or properties file in CE** (only
`kotlin` (JVM) and `android-kotlin`). Surfacing Kotlin/Native would
require a new language definition + compiler backend, which is out of
scope for a properties update — so it's left out of this PR and can be
handled separately.
## Testing
Ran local discovery for each affected language (`node app.ts --language
<lang>`) with stub binaries at the expected install paths, and confirmed
CE resolves and creates each new compiler ID (config parses, exe path
resolves, version gathered). The pre-commit `test:props` validation
suite passes (90/90).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Part of the actionlint rollout across CE repos
(compiler-explorer/compiler-workflows#68, compiler-explorer/infra#2226).
[actionlint](https://github.com/rhysd/actionlint) statically checks
workflow files: schema/typos, expression type-checking against real
contexts (undefined inputs/outputs/needs are errors), unknown runner
labels, and shellcheck over embedded `run:` scripts.
This repo has no pre-commit framework, so it's wired as a small CI
workflow that runs on any push/PR touching `.github/workflows/**`, using
the pinned official docker image. `.github/actionlint.yaml` declares the
self-hosted `admin` label so `runs-on: [admin]` (deploy workflows)
checks correctly.
The existing ten workflows already pass with no findings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
*(I'm Molty, an AI assistant acting on behalf of @mattgodbolt)*
Adds SDCC 4.6.0 to the C compiler list. Requested because 4.6.0 is the
first C compiler release to support the `_Optional` type qualifier.
Follows the existing SDCC group convention exactly: appends `sdcc460` to
`group.sdcc.compilers` and adds the `exe`/`semver` entries. No existing
IDs changed.
Depends on the infra install PR landing first:
compiler-explorer/infra#2228
Verified the 4.6.0 tarball installs via `ce_install`, `bin/sdcc
--version` reports `4.6.0`, and a `_Optional int *p;` program compiles
cleanly. The properties validation suite passes (`npm run test:props`,
90 tests).
🤖 Generated by LLM (Claude, via OpenClaw)
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
*(I'm Molty, an AI assistant acting on behalf of @mattgodbolt)*
## Problem
Compilers in the `clangx86trunk` group that set their own `options`
property silently **override** the group-level
`options=--gcc-toolchain=/opt/compiler-explorer/gcc-snapshot`. The
per-compiler value is checked first; if found, the group fallback is
never reached.
This means ~18 compilers (all those with a per-compiler `options` line —
e.g. `clang_hana`, `clang_bb_p2996`, `clang_p2998`, `clang_patmat`,
`clang_resugar`, `clang_barry`, `clang_concepts`, etc.) fall back to the
system GCC 13 instead of `gcc-snapshot`. System GCC 13's libstdc++ lacks
headers like `bits/version.h`, so any user who switches these compilers
to `-stdlib=libstdc++` gets:
```
fatal error: 'bits/version.h' file not found
```
Reported via: https://compiler-explorer.com/z/WcPd19b5o (hana-clang, but
confirmed broken on all affected compilers).
## Fix
Move the toolchain flag from `group.clangx86trunk.options` to
`group.clangx86trunk.baseOptions`. The `baseOptions` and `options`
values are **concatenated** rather than one replacing the other, so
per-compiler `options` no longer silently discard the toolchain.
`clang_p1144` and `clang_lifetime` intentionally use different GCC
toolchains, so they get their own `baseOptions` override with the
correct path. The toolchain flag is removed from their `options` entries
(which now only contain the non-toolchain flags).
## Testing
Verified via CE compile API with `-v` that:
- Affected compilers (e.g. `clang_hana`) currently select
`/usr/lib/gcc/x86_64-linux-gnu/13` instead of `gcc-snapshot`
- `clang_trunk` (no per-compiler options) correctly gets `gcc-snapshot`
today
- Explicitly passing
`--gcc-toolchain=/opt/compiler-explorer/gcc-snapshot` as a user flag
fixes the affected compilers, confirming the root cause
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Fixes#8896.
### What was happening
`SharingBase.ensureUrlIsNotOutdated()` replaces the page URL with
`httpRoot` (`/`) once the layout state diverges from the state recorded
after load. That rewrite exists for the main site, so an outdated
shortlink path (`/z/...`) doesn't linger in the address bar after you
edit the code.
Since #8166 started running the shared state-tracking (`SharingBase`) in
embedded mode too — to keep the "Edit on Compiler Explorer" link in sync
— the rewrite also fires inside `/e` iframes. There, `location.pathname`
(`/e`) never equals `httpRoot` (`/`), so the first state change after
load (an edit, or just layout churn) silently rewrites the iframe's URL
to `/` — dropping both the `/e` path **and** the state hash. Reproduced
with a `history.replaceState` spy: after two edits in an embed, the
iframe's location is `/` with an empty hash.
The visible symptoms are then browser-dependent, which is why it looked
intermittent: Firefox restores an iframe's *session-history* URL when
the parent page reloads, so the iframe comes back as `godbolt.org/` —
the full site, showing the default language example, and (because
cookies are unreadable in a cross-site iframe, per the `privacy_status`
SameSite console error in the report) the privacy-policy popup. Chrome
reloads iframes from their `src` attribute, so it never showed the
problem.
### The fix
Skip the rewrite entirely in embedded mode — the iframe's URL *is* the
embedded state and must never be touched. The `a.link` "Edit on Compiler
Explorer" state tracking from #8166 is unaffected.
### Tests
New `cypress/e2e/embed.cy.ts`:
- the embedded state's code loads (not the default example),
- the `/e#state` URL survives state changes (fails before this fix:
pathname becomes `/`, hash emptied),
- the "Edit on Compiler Explorer" link still picks up edits (locks in
#8166's behaviour).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
It lowers to the exact value as limited by lint-staged package. For some
reason, the value is chosen to be the current LTS value at the time of
this
[PR](https://github.com/compiler-explorer/compiler-explorer/pull/8885)
even though the value is dictated by lint-staged package.
Follow up of
https://github.com/compiler-explorer/compiler-explorer/pull/8849
Thanks a lot for the review and merge !
I did not realize that scale/1.7.1 does not support cuda>13.1 as I was
testing locally with cuda/12.8.0, see
https://godbolt.org/z/cjdvYqGbd
> nvcc: warning: CUDA version is newer than the latest supported version
13.1 [-Wunknown-cuda-version]
The fix is straightforward and included in this PR. AMD backend seems
good. Sorry for the noise :)
Regards
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.7
to 48.0.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>48.0.1 - 2026-06-09</p>
<pre><code>
* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL
4.0.1.
<p>.. _v48-0-0:</p>
<p>48.0.0 - 2026-05-04<br />
</code></pre></p>
<ul>
<li>
<p><strong>BACKWARDS INCOMPATIBLE:</strong> Support for Python 3.8 has
been removed.
<code>cryptography</code> now requires Python 3.9 or later.</p>
</li>
<li>
<p><strong>BACKWARDS INCOMPATIBLE:</strong> Loading an X.509 CRL whose
inner
<code>TBSCertList.signature</code> algorithm does not match the outer
<code>signatureAlgorithm</code> now raises <code>ValueError</code>.
Previously, such CRLs
were parsed successfully and only rejected during signature
validation.</p>
</li>
<li>
<p>Added support for
:doc:<code>/hazmat/primitives/asymmetric/mlkem</code> and
:doc:<code>/hazmat/primitives/asymmetric/mldsa</code> when using OpenSSL
3.5.0 or
later, in addition to the existing AWS-LC and BoringSSL support. This
means
post-quantum algorithms are now available to users of our wheels.</p>
<ul>
<li><strong>Note:</strong> Going forward, we do not guarantee that all
functionality
in <code>cryptography</code> will be available when building against
OpenSSL. See :doc:<code>/statements/state-of-openssl</code> for more
information.</li>
</ul>
</li>
</ul>
<p>.. _v47-0-0:</p>
<p>47.0.0 - 2026-04-24</p>
<pre><code>
* Support for Python 3.8 is deprecated and will be removed in the next
``cryptography`` release.
* **BACKWARDS INCOMPATIBLE:** Support for binary elliptic curves
(``SECT*`` classes) has been removed. These curves are rarely used and
have additional security considerations that make them undesirable.
* **BACKWARDS INCOMPATIBLE:** Support for OpenSSL 1.1.x has been
removed.
OpenSSL 3.0.0 or later is now required. LibreSSL, BoringSSL, and AWS-LC
continue to be supported.
* **BACKWARDS INCOMPATIBLE:** Dropped support for LibreSSL < 4.1.
* **BACKWARDS INCOMPATIBLE:** Loading keys with unsupported algorithms
or
keys with unsupported explicit curve encodings now raises
:class:`~cryptography.exceptions.UnsupportedAlgorithm` instead of
``ValueError``. This change affects
:func:`~cryptography.hazmat.primitives.serialization.load_pem_private_key`,
:func:`~cryptography.hazmat.primitives.serialization.load_der_private_key`,
:func:`~cryptography.hazmat.primitives.serialization.load_pem_public_key`,
:func:`~cryptography.hazmat.primitives.serialization.load_der_public_key`,
and :meth:`~cryptography.x509.Certificate.public_key` when called on
certificates with unsupported public key algorithms.
</tr></table>
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="de987ce48c"><code>de987ce</code></a>
48.0.1 version bump and changelog (<a
href="https://redirect.github.com/pyca/cryptography/issues/14996">#14996</a>)</li>
<li><a
href="8e03e30e3a"><code>8e03e30</code></a>
bump for 48.0.0 release (<a
href="https://redirect.github.com/pyca/cryptography/issues/14796">#14796</a>)</li>
<li><a
href="295e0d254e"><code>295e0d2</code></a>
Add AGENTS.md with CLAUDE.md symlink (<a
href="https://redirect.github.com/pyca/cryptography/issues/14794">#14794</a>)</li>
<li><a
href="104a2de19e"><code>104a2de</code></a>
Bump BoringSSL, OpenSSL, AWS-LC in CI (<a
href="https://redirect.github.com/pyca/cryptography/issues/14793">#14793</a>)</li>
<li><a
href="67ec1e5198"><code>67ec1e5</code></a>
call check_length early on AesSiv::encrypt (<a
href="https://redirect.github.com/pyca/cryptography/issues/14792">#14792</a>)</li>
<li><a
href="b2da57a0d9"><code>b2da57a</code></a>
changelog for mldsa/mlkem for openssl (<a
href="https://redirect.github.com/pyca/cryptography/issues/14791">#14791</a>)</li>
<li><a
href="3cf44adee2"><code>3cf44ad</code></a>
ML-KEM OpenSSL support (<a
href="https://redirect.github.com/pyca/cryptography/issues/14781">#14781</a>)</li>
<li><a
href="2e31639666"><code>2e31639</code></a>
ML-DSA OpenSSL support (<a
href="https://redirect.github.com/pyca/cryptography/issues/14773">#14773</a>)</li>
<li><a
href="5affe5a286"><code>5affe5a</code></a>
fix rust nightly clippy (<a
href="https://redirect.github.com/pyca/cryptography/issues/14790">#14790</a>)</li>
<li><a
href="2e73ca448e"><code>2e73ca4</code></a>
bump rust-openssl dep and update EcPoint::mul_generator to
mul_generator2 (<a
href="https://redirect.github.com/pyca/cryptography/issues/1">#1</a>...</li>
<li>Additional commits viewable in <a
href="https://github.com/pyca/cryptography/compare/46.0.7...48.0.1">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/compiler-explorer/compiler-explorer/network/alerts).
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps and [form-data](https://github.com/form-data/form-data). These
dependencies needed to be updated together.
Updates `form-data` from 2.5.5 to 2.5.6
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/form-data/form-data/blob/master/CHANGELOG.md">form-data's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/form-data/form-data/compare/v2.5.5...v2.5.6">v2.5.6</a>
- 2026-06-12</h2>
<h3>Commits</h3>
<ul>
<li>[Fix] escape CR, LF, and <code>"</code> in field names and
filenames <a
href="b62031603c"><code>b620316</code></a></li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code>,
<code>auto-changelog</code>, <code>eslint</code>, <code>tape</code> <a
href="12be578e93"><code>12be578</code></a></li>
<li>[Dev Deps] update <code>js-randomness-predictor</code> <a
href="46cfd23bd4"><code>46cfd23</code></a></li>
<li>[Tests] use <code>safe-buffer</code> so the header-injection test
runs on node < 4 <a
href="633044a57a"><code>633044a</code></a></li>
<li>[Deps] update <code>hasown</code> <a
href="e3b96eef16"><code>e3b96ee</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c7133499c2"><code>c713349</code></a>
v2.5.6</li>
<li><a
href="46cfd23bd4"><code>46cfd23</code></a>
[Dev Deps] update <code>js-randomness-predictor</code></li>
<li><a
href="633044a57a"><code>633044a</code></a>
[Tests] use <code>safe-buffer</code> so the header-injection test runs
on node < 4</li>
<li><a
href="e3b96eef16"><code>e3b96ee</code></a>
[Deps] update <code>hasown</code></li>
<li><a
href="12be578e93"><code>12be578</code></a>
[Dev Deps] update <code>@ljharb/eslint-config</code>,
<code>auto-changelog</code>, <code>eslint</code>, <code>tape</code></li>
<li><a
href="b62031603c"><code>b620316</code></a>
[Fix] escape CR, LF, and <code>"</code> in field names and
filenames</li>
<li>See full diff in <a
href="https://github.com/form-data/form-data/compare/v2.5.5...v2.5.6">compare
view</a></li>
</ul>
</details>
<br />
Updates `form-data` from 4.0.5 to 4.0.6
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/form-data/form-data/blob/master/CHANGELOG.md">form-data's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/form-data/form-data/compare/v2.5.5...v2.5.6">v2.5.6</a>
- 2026-06-12</h2>
<h3>Commits</h3>
<ul>
<li>[Fix] escape CR, LF, and <code>"</code> in field names and
filenames <a
href="b62031603c"><code>b620316</code></a></li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code>,
<code>auto-changelog</code>, <code>eslint</code>, <code>tape</code> <a
href="12be578e93"><code>12be578</code></a></li>
<li>[Dev Deps] update <code>js-randomness-predictor</code> <a
href="46cfd23bd4"><code>46cfd23</code></a></li>
<li>[Tests] use <code>safe-buffer</code> so the header-injection test
runs on node < 4 <a
href="633044a57a"><code>633044a</code></a></li>
<li>[Deps] update <code>hasown</code> <a
href="e3b96eef16"><code>e3b96ee</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c7133499c2"><code>c713349</code></a>
v2.5.6</li>
<li><a
href="46cfd23bd4"><code>46cfd23</code></a>
[Dev Deps] update <code>js-randomness-predictor</code></li>
<li><a
href="633044a57a"><code>633044a</code></a>
[Tests] use <code>safe-buffer</code> so the header-injection test runs
on node < 4</li>
<li><a
href="e3b96eef16"><code>e3b96ee</code></a>
[Deps] update <code>hasown</code></li>
<li><a
href="12be578e93"><code>12be578</code></a>
[Dev Deps] update <code>@ljharb/eslint-config</code>,
<code>auto-changelog</code>, <code>eslint</code>, <code>tape</code></li>
<li><a
href="b62031603c"><code>b620316</code></a>
[Fix] escape CR, LF, and <code>"</code> in field names and
filenames</li>
<li>See full diff in <a
href="https://github.com/form-data/form-data/compare/v2.5.5...v2.5.6">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/compiler-explorer/compiler-explorer/network/alerts).
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Keep only the newest patch build for each minor series (0.19-0.27).
Removed compiler IDs are preserved as aliases on the surviving
latest-patch compiler so existing shortlinks keep resolving.
Infra PR: https://github.com/compiler-explorer/infra/pull/2210
Co-authored-by: Claude <noreply@anthropic.com>
Hi !
This PR adds the [scale nvcc
compiler](https://docs.scale-lang.com/stable/) to the CE live site for
both AMD and Nvidia backends
It works locally and shows host asm, device LLVMIR and:
- PTX ans SASS for Nvidia backend,
- AMDGPU code for AMD backend.
There is a bug in scale 1.7.1 that prevents the compilation with both
`-S, -o` flags. As a result I had to make some temp workarounds.
For Nvidia backend, PTX is written in the device `.s` file. I run it
through `ptax` and `nvidasm` to get the SASS. To get the LLVMIR, I
decode the device `.bc` file with `llvm-dis`.
For AMD backend, the `.s` file is the AMDGPU code, and the LLVMIR is
obtained the same way.
I plan to make the `.ts` script closer to say `nvcc.ts` once the flag
bugs are fixed in scale.
Let me know if there is anything I missed for the live site integration.
infra PR: https://github.com/compiler-explorer/infra/pull/2191
Issue:
https://github.com/compiler-explorer/compiler-explorer/issues/8865
I acknowledge the use of generative AI to help drafting the code of this
PR.
---------
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## What
Fresh rollup of minor/patch dependency updates via `npm update -S`, plus
a
`biome.json` tweak, plus a **node floor move to the latest 22 LTS**.
Redo of #8844
on top of current `main`.
Notable dep bumps: `@aws-sdk/*` 3.1057→3.1079, `@sentry/*` 10.55→10.63,
`webpack` 5.107→5.108, `@biomejs/biome` 2.4.16→2.5.2, `cypress`, `sass`,
`lint-staged`, and others.
## biome `!**/*.svg`
biome 2.5 now parses `.svg` files as HTML and errors on them (94 errors
across
`static/**`/`public/**`). Added `!**/*.svg` to the biome ignore list.
## Node floor → 22.23.1 (latest 22 LTS)
The update pulled `lint-staged@17.0.8`, which requires node `>=22.22.1`
— above our
previous declared minimum of `22.12.0`. Per the #8845 `find-node`
contract,
`.node-version` is the single source of truth whose satisfaction must
also satisfy
`engines.node` and every dependency. To keep that true, this bumps:
- `.node-version` → `22.23.1`
- `engines.node` → `>=22.23.1`
22.23.1 is the current latest 22 LTS and is also what CI's `setup-node`
(`22.x` +
`check-latest`) already resolves to. **Production node should move to
match.**
Lockfile regenerated cleanly under node 22.23.1 / npm 10.9.8 (CI's
toolchain).
## No `webpackJsHack` bump
The original #8844 also bumped `webpackJsHack` to dodge a source-map CDN
hash
collision; #8848 removed that escape hatch entirely (infra#2188 exempted
source
maps). So this touches no `webpack.config.esm.ts`.
## Note on the earlier biome CI failure
An earlier push failed `test` with `Cannot find module
'@biomejs/cli-linux-x64/biome'`.
Investigated: the lockfile is complete (all 8 platform optional deps
present, biome
2.5.2's package metadata is byte-identical to 2.4.16 which passes on
`main`), it
installs fine under npm 10.9/11.8 locally, and node 22.23.1 satisfies
all engines.
This is the known nondeterministic npm optional-dependency install flake
(npm/cli#4828) under node-22's bundled npm 10.9 — not a lockfile/code
defect. It
resolves on re-run; the systemic fix (make CI install with the repo's
declared
`npm@11.2.0` via corepack) is out of scope here.
Supersedes #8844.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
> [!IMPORTANT]
> **Draft / do not merge yet.** Depends on
[infra#2188](https://github.com/compiler-explorer/infra/pull/2188) being
merged **and deployed** first. Until then, this `webpackJsHack` constant
is still the only escape hatch for the source-map hash collisions, so it
must stay. There's no deadline on this PR — it's pure cleanup that can
wait indefinitely.
## What
Removes the `webpackJsHack` `.vNN.` infix from the static asset
filenames (`[name].vNN.[contenthash].js` → `[name].[contenthash].js`,
and likewise for `.css` and worker files), along with its now-misleading
"Hack alert" comment.
## Why
This constant was a **manual escape hatch**. The CDN serves static files
with a one-year immutable cache and verifies (in CI, `ce ... builds
check_hashes`) that a given filename never changes content. Source maps
are named after their *asset's* content hash (`<asset>.map`), so a
toolchain bump that regenerated a map for byte-identical JS/CSS reused
the same `.map` filename with different bytes → the check failed, and we
manually bumped this constant to rename every asset and dodge the
collision.
[infra#2188](https://github.com/compiler-explorer/infra/pull/2188) fixes
the root cause: source maps are debug-only metadata, not code, so
they're now exempt from the immutable-hash check, overwritten on deploy,
and served `no-cache` (so debugging always gets the current map). With
that deployed, this constant can never need bumping again.
## The comment was true once — on webpack 4 — but has been obsolete
since the webpack 5 upgrade
The "Hack alert" comment claims the bumps are needed for *"webpack
changes that affect how minification is done, even though that's
supposed not to matter."* That was accurate when it was written, but
stopped being true years ago:
| When | webpack | What | Minification claim valid? |
|------|---------|------|---------------------------|
| 2020-04-18 (`67575197f`, *"Add a hacky fix for the cannot upload over
identical file"*) | **4.42.1** | Comment + manual version introduced;
template changed `[chunkhash]` → `v2.[contenthash]` | **Yes** |
| 2021-12-21 (`7c20613c5`, *"Move to using webpack5 (#3197)"*) |
**5.65.0** | Upgrade to webpack 5 | **No — obsolete from here on** |
- **On webpack 4** there was no `realContentHash`; JS hashes were
computed from the chunk's module content *before* Terser ran. So a
webpack/minifier change that altered the *minified* output left the hash
unchanged → same filename, different bytes → "cannot upload over
identical file". The manual version was a genuine fix, and the comment
correctly described pre-minification hashing.
- **Since webpack 5** (`realContentHash: true`, default-on in
production, landed in 5.8) every `[contenthash]` is recomputed from the
**final, post-minification** bytes. A minifier change now produces a
*new filename* on its own — it can no longer collide. So the
minification rationale has been dead for ~3.5 years.
That means essentially every version bump from the webpack-5 era onward
(the `v2 → … → v69` march) was a **source-map** collision misattributed
to minification — the source map being the one asset whose name still
isn't a hash of its own post-processed content. That is exactly what
infra#2188 addresses.
### Net
- A real code change or a minifier change → different post-minification
bytes → different `[contenthash]` → new filename. Handled correctly by
content-addressing; no hack needed.
- The only same-name-different-bytes case was source maps → fixed by
infra#2188.
- So removing `webpackJsHack` (and its misleading comment) is safe once
infra#2188 is deployed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
## What
Reworks the bespoke `etc/scripts/find-node` and its `Makefile`
interaction so node discovery works out of the box on Linux and macOS,
is optionally friendly to version managers, and stays sympathetic to
people who just use system node.
### Before
- Only ever looked at `PATH`, plus a vestigial
`/opt/compiler-explorer/node` hardcode (an affordance for one dev's
local setup, unused by the live site).
- Duplicated the required node version in three places (`find-node` had
`22` twice; `.node-version`; `package.json` `engines`).
- Silently fell back *past* an unusable `NODE_DIR` to whatever else it
found.
- nvm users got whatever default was active, not the version this repo
pins.
- Nagged on any version that wasn't exactly `22.x`, even newer ones.
### After — clear, permissive resolution order
1. **`$NODE_DIR/bin/node`** — explicit override, now authoritative. If
it's set but missing/too old you get a clear error instead of a silent
fallback.
2. **`node`/`nodejs` on `PATH`** — covers system node *and* any version
manager with shell integration (fnm, asdf, nodenv, volta, an active
nvm). Zero extra steps on a well-configured machine.
3. **Manager rescue** — only when PATH node is absent or below the
minimum: source `nvm` and ask for the pinned version (the one manager
that's a shell function rather than a PATH binary), then try
`fnm`/`nodenv`/`asdf`. Each branch is inert unless that tool is
installed, so nobody is pushed onto a manager.
Other changes:
- **Single source of truth**: the minimum major now comes solely from
`.node-version` (the same file the managers read). Newer majors are
always fine — the "only tested against v22.x" warning is dropped.
- **`Makefile`**: `.node-bin` now also depends on `.node-version`, so
bumping the pin re-resolves node instead of serving a stale cache. The
lazy-dotfile pattern (so failures abort `make` and `make help` pays
nothing) is kept.
- **`README`**: documents the PATH-first + manager-rescue behaviour.
## Testing
- `shellcheck` clean.
- Verified: PATH discovery, valid/bogus `NODE_DIR`, nvm rescue (shadowed
`node`+`nodejs` with v18 shims → skipped them and resolved v22.22 via
nvm), too-old fallthrough, no-node/no-manager failure message, and `make
info` end-to-end.
- `fnm` branch is logically straightforward but was not exercised (no
fnm on the test box) — worth a smoke test if you have one.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Matt Godbolt <matt@godbolt.org>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Add Mojo **1.0.0b2**, published to PyPI on 2026-06-18.
- Appends `mojo_1_0_0b2` to the `group.mojo.compilers` list (before
`mojo_nightly`).
- Adds the `exe` and `semver` properties for
`/opt/compiler-explorer/mojo-1.0.0b2/bin/mojo`.
Existing `mojo_0_25_6_0`, `mojo_0_25_7_0`, `mojo_0_26_1_0`,
`mojo_0_26_2_0`, and `mojo_1_0_0b1`
entries are deliberately kept per [docs/AddingACompiler.md § "Don't
remove or rename compilers on
the public
site"](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/AddingACompiler.md#dont-remove-or-rename-compilers-on-the-public-site).
**Companion infra PR required:** a matching change in
`compiler-explorer/infra`
(`bin/yaml/mojo.yaml`, `type: pip`, `mojo==1.0.0b2`) is needed to
install the binary on the public
site. That is in a separate repository and not included here.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## What & why
We used to enforce the BSD-2-Clause license banner on every source file
via `eslint-plugin-header`. That check was lost when we migrated from
ESLint to Biome (#7033), which has no equivalent rule. This PR
reinstates it as a standalone node script, modelled on the existing
`etc/scripts/check-frontend-imports.js`.
### Why a script rather than a Biome rule
Biome 2.x has no built-in license/header rule and no plugin equivalent
to `eslint-plugin-header`; its experimental GritQL plugins aren't suited
to whole-file-prefix matching. A script needs zero new dependencies and
gives full control over scope and exemptions.
## The check (`etc/scripts/check-license-headers.js`)
A file "has an appropriate banner" if, ignoring an optional shebang, it
opens with a `// Copyright (c) …` line **and** contains the BSD-2-Clause
disclaimer body. The year and copyright holder are intentionally **not**
constrained — the tree legitimately has many holders (Compiler Explorer
Authors, Arm, Microsoft, HRT, individuals). The `(c)`/`(C)` marker is
matched case-insensitively.
**Scope:** `.ts/.js/.mjs/.cjs` under `lib/ static/ shared/ types/ test/
cypress/`.
**Exempt:** generated files (`lib/asm-docs/generated`), vendored
(`docenizer/vendor`), `.d.ts`, and three third-party ports that carry
their own upstream license — `static/ansi-to-html.ts` (MIT),
`lib/node-graceful.ts` (MIT), `shared/rison.ts` (Nanonid/rison port).
**Wired into:** CI (`test-and-deploy.yml`), `npm run check`, the `make
pre-commit` target, the husky pre-commit hook, and `lint-staged` (per
staged file).
Usage:
```
node ./etc/scripts/check-license-headers.js # scan the tracked tree
node ./etc/scripts/check-license-headers.js <files...> # scan specific files (lint-staged)
```
## Backfill
The check surfaced **42 CE-authored files** missing the banner. This PR
backfills them all with the standard `Copyright (c) <year>, Compiler
Explorer Authors` banner, using each file's **git creation year**
(added-at-this-path, so no `--follow` rename artifacts).
## Verification
- `check-license-headers` → clean (was 42 failures)
- `biome check` on all source → no fixes needed (banner format matches
existing convention)
- `tsc` backend + frontend + tests → clean
- pre-commit gauntlet (lint, ts-check, related tests: 528 passed) ran on
commit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bumps the RazorForge compiler from `0.0.4-alpha` to the `0.1.0` release
(initial support added in #8825).
v0.1.0 is the first stable (non-`-alpha`) tag, so the install path drops
the `-alpha` suffix:
`/opt/compiler-explorer/razorforge-0.0.4-alpha/RazorForge` →
`/opt/compiler-explorer/razorforge-0.1.0/RazorForge`.
The matching install recipe is in compiler-explorer/infra#2192 (tarball
URL verified `200`).
Exposes mainline **gcc 14.4.0** and **15.3.0** (x86-64), plus their
assertions variants, in the **C** and **C++** compiler dropdowns.
### Why
This is the missing "expose in the UI" half of adding these gcc
versions. compiler-explorer/infra#2203 already *installs* them (the S3
artifacts are built), but without matching `.properties` entries they
don't appear in CE. cc @Yashinde145 — this is the companion PR to your
infra#2203; the version bump needs a change here too so the compilers
actually show up.
### What
Following the existing `g152`/`g143` pattern:
- `c++.amazon.properties`: `g144`, `g153` (+ `g144assert`, `g153assert`)
entries + added to `group.gcc86.compilers` /
`group.gcc86assert.compilers`.
- `c.amazon.properties`: the mirrored `cg144`, `cg153` (+ assertions)
entries + group lists (the shared gcc install serves both C and C++).
`test:props` passes (ran via the pre-commit hook). Only the C/C++
dropdowns are touched; other gcc-family languages (fortran/ada/d/…)
track gcc separately and could be extended in a follow-up if wanted.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Summary
- resolve nested named MLIR location aliases in the MLIR asm parser
- strip MLIR location metadata from displayed device output
- make Device Viewer source colours and hover linkage use the owning
source editor
## Testing
- npm run test -- test/asm-parser-tests.ts --reporter dot
- npm run ts-check:frontend
- npm run ts-check:backend
- npm run ts-check:tests
- npx biome check lib/parsers/asm-parser-mlir.ts
test/asm-parser-tests.ts static/panes/device-view.ts
- git diff --check -- lib/parsers/asm-parser-mlir.ts
test/asm-parser-tests.ts static/panes/device-view.ts
- pre-commit hook: npm run lint, npm run ts-check, vitest related passed
Note: a standalone npm run test-min run failed in unrelated
test/demangler-tests.ts Rust demangling expectations in this local
environment.
---------
Co-authored-by: Matt Godbolt <matt@godbolt.org>
This PR adds [CO2](https://github.com/hkalbasi/co2) which is a language
backward compatible with C, with some Rust interop features that
compiles to Rust's MIR.
I added two compiler `co2rustc` and `co2cc`, and a tool `co2miri` which
is Miri for CO2. I added `co2cc` under C compilers, to make it possible
to view diff of assembly for a C code compiled with CO2 and clang or
gcc. `co2cc` is a CO2 frontend which accepts gcc-like flags, and can (or
at least should) compile almost every ISO compatible C23 code.
`co2rustc` accepts Rust like flags, and added under a new `CO2`
language.
Tested locally and it seems to work.
I need some help in setting up artifacts (which, if I understand
correctly, needs to happen in `infra` or `compiler-workflows`). I make
an artifact `co2-multicall` in my CI, which needs to get symlinked in
`co2cc`, `co2rustc` and `co2miri`, and it needs to run a simple project
with miri to create the miri sysroot. If you show me a similar project,
I will do the job.
Disclaimer: Written partially by LLM.
---------
Co-authored-by: Matt Godbolt <matt@godbolt.org>
3 Separate optimizations towards resolution of #8583:
1. (probably most substantial:) ``PrefixTree.replaceAll` did O(n^2)
allocations, causing substantial GC time:
```ts
const lineBit = line.substring(idxInOld);
const [oldValue, newValue] = this.findLongestMatch(lineBit);
```
For every character pos in a line this allocated a substring for the
entire remainder. Over one line that's O(n^2) bytes allocated, and
`processPassOutput` runs this on every line of every before/after IR
dump — which for an opt-pipeline run is enormous. This is a major
contributor to both the `replaceAll`/`processPassOutput` self-time and
the 20% GC.
Fix: make `findLongestMatch` accept a start offset and walk the existing
line string in place.
2. `JSON.stringify` large payloads once instead of twice, when caching
to S3
3. `processPassOutput` called `PrefixTree.replaceAll` which did a costly
build of replacement map but didn't use them. Now calls the new
`PrefixTree.replaceAllText`.
-------
The time measurements on the live site and on my machine differ
substantially. Before pursuing more aggressive optimizations I want to
check the impact of these, see if more work is needed.
One additional direction for (major) optimization: I think today each
pass dump is processed twice, once as 'before' and 2nd time as 'after'
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>