Repository navigation
clang 23.1.0: MSVC STL std module fails with reference to 'align_val_t' is ambiguous (fixed in 23.1.1, llvm/llvm-project#218152) #640
Description
Summary
clang 23.1.0 cannot build the MSVC STL std module. Every compile of std.ixx stops in vcruntime_new.h:
vcruntime_new.h:97:12: error: reference to 'align_val_t' is ambiguous
97 | ::std::align_val_t _Al
| ^
vcruntime_new.h:27:33: note: candidate found by name lookup is 'std::align_val_t'
27 | _VCRT_EXPORT_STD enum class align_val_t : size_t {};
| ^
note: candidate found by name lookup is 'std::align_val_t'
The candidate without a source location is the std::align_val_t clang declares implicitly for aligned allocation, the "predefined decl from std" the upstream fix is about. MSVC STL builds its std module by including the STL inside extern "C++" in the module's purview, so the enum from vcruntime_new.h is exported with global-module attachment. clang 23.1.0 does not merge it with the implicit declaration, and the lookup finds both.
This is a clang regression. Upstream it is llvm/llvm-project#218152, bisected to llvm/llvm-project#187347 and fixed by llvm/llvm-project#219151, which was cherry-picked to release/23.x and ships in clang 23.1.1. clang 22.1.8 and 23.1.1 build the same sources cleanly; of the final releases, only 23.1.0 is affected.
Nothing in mcpp breaks today, because the index's newest LLVM is 22.1.8. Filing so that the move to LLVM 23 skips 23.1.0, and so that anyone who sees "ambiguous align_val_t" in std.ixx finds the cause and the two ways around it.
Where it bit
lsp-mcpp ships clangd 23.1.0 as its semantic engine. clangd 23.1.0 could not build std for any Windows project that uses import std with the MSVC STL: clangd --check on std.ixx failed in both driver modes, with and without a developer environment. That covers cl.exe, clang-cl, and clang++ targeting x86_64-pc-windows-msvc, including mcpp's llvm@22.1.8 and msvc@system projects. Every file importing std then had no semantic results. The clang 23.1.0 compiler from the official release fails the same way, so it is a frontend defect, not a clangd one.
lsp-mcpp now passes aligned-allocation-off to every unit of an MSVC STL context for clangd 23.x (below) and will move its payload to clangd 23.1.1.
Minimal reproducer (no headers, any host)
// repro.cppm
export module m;
extern "C++" {
namespace std {
using size_t = decltype(sizeof(0));
export enum class align_val_t : size_t {};
}
void* operator new(std::size_t);
void* operator new(std::size_t, ::std::align_val_t);
}clang++ -std=c++23 -c -x c++-module repro.cppm -fmodule-output=m.pcm -o m.oWith clang 23.1.0 (ea7d852a70e8bdfaf601d6626a760f9771b2c4b4):
repro.cppm:8:40: error: reference to 'align_val_t' is ambiguous
repro.cppm:5:19: note: candidate found by name lookup is 'std::align_val_t'
1 error generated.
It reproduces on both Linux x86_64 (ubuntu-24.04) and Windows (windows-2022) with the official 23.1.0 release. clang 23.1.1 (6dfe1677ab8dffbc6ec13d53a1e0215d75147689) and clang 22.1.8 (ca7933e47d3a3451d81e72ac174dcb5aa28b59d1) compile it without diagnostics.
What does and does not trigger it
Variant of repro.cppm |
clang 23.1.0 |
|---|---|
| As above | ambiguous |
operator delete(void*) noexcept instead of operator new(std::size_t) |
ambiguous |
As above, -fno-aligned-allocation |
ok |
align_val_t not exported |
ok |
| No plain allocation function declared between the enum and its use | ok |
The plain operator new declared before the enum |
ok |
| Same declarations in an ordinary translation unit (no module) | ok |
The ingredients are:
- An exported
std::align_val_tdeclared insideextern "C++"in a module interface. - After it, the declaration of a replaceable global allocation or deallocation function, which makes clang declare the global
new/deletefamily implicitly,std::align_val_tincluded. - A later reference to
std::align_val_t.
vcruntime_new.h has all three in that order. The first and third rows were measured with the compilers from the official releases; the remaining rows with the frontend of clangd 23.1.0 (the same llvm-project revision) through clangd --check.
The MSVC STL case
windows-2022 image 20260907.297.1: Visual Studio 17.14.39, MSVC tools 14.44.35207, Windows SDK 10.0.26100.0. Run in a developer command prompt with the official LLVM releases:
clang --driver-mode=g++ --target=x86_64-pc-windows-msvc -std=c++23 \
-Wno-reserved-module-identifier -Wno-include-angled-in-module-purview \
-c -x c++-module "%VCToolsInstallDir%modules\std.ixx" -fmodule-output=std.pcm -o std.obj| clang | default | -fno-aligned-allocation |
|---|---|---|
| 23.1.0 | error at vcruntime_new.h:97:12 and :103:12 (ambiguous align_val_t) |
ok |
| 23.1.1 | ok | ok |
| 22.1.8 | ok | ok |
The include chain to the error is std.ixx:43 → <algorithm> → __msvc_heap_algorithms.hpp → xutility → yvals.h → crtdbg.h → vcruntime_new_debug.h → vcruntime_new.h. In an earlier run, clang-cl 23.1.0 building a .cppm copy of std.ixx failed the same way, and /Zc:alignedNew- fixed it.
Evidence: lsp-mcpp CI probe runs 34843950329 (the matrix above plus repro.cppm on Linux and Windows) and 34806339903 (clang-cl and clangd). Both ran on throwaway branches of Sunrisepeak/lsp-mcpp-private.
Workarounds
- Use clang 23.1.1 or later (or stay on 22.1.8). This is the actual fix.
- With 23.1.0 only: turn aligned allocation off for every unit of the context. Use
-fno-aligned-allocation(GNU driver) or/Zc:alignedNew-(cl driver).AlignedAllocationis an ordinary language option that must match between a module and its importers, so it cannot be set onstd.ixxalone.- The semantic cost: a
newexpression for an over-aligned type no longer selects thestd::align_val_toverloads. - This is what lsp-mcpp does for clangd 23.1.0; with it, clangd builds
std,std.compatand user modules with no errors and no developer environment.
Ask for mcpp
- When LLVM 23 enters the index, or becomes the default Windows toolchain, go straight to 23.1.1 or later. If 23.1.0 has to be offered, either mark it as unable to build the MSVC STL
stdmodule, or add workaround 2 for*-windows-msvctargets using the MSVC STL, keyed on that exact version. - A line in the C++ modules known-issues documentation: "clang 23.1.0:
reference to 'align_val_t' is ambiguouswhen building the MSVC STLstdmodule; fixed in 23.1.1 (align_val_tis ambiguous under MSVC in a module llvm/llvm-project#218152); or build every unit with-fno-aligned-allocation."
Upstream
align_val_tis ambiguous under MSVC in a module llvm/llvm-project#218152 — "align_val_tis ambiguous under MSVC in a module" (closed; bisected to [Sema] Add implicit std::align_val_t to std namespace DeclContext for module merging llvm/llvm-project#187347)- [C++20] [Modules] Handling merging predefined decls from std llvm/llvm-project#219151 — "[C++20] [Modules] Handling merging predefined decls from std", merged 2026-08-27; cherry-picked to
release/23.xas99cfc877e40b1fff9f006129db9f7895a7847ce3and included inllvmorg-23.1.1
Activity
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
Move the LLVM line to 23.1.3 and the macOS/Windows host defaults with it
nico commentedon Oct 13, 2026
I think this is a dupe of llvm/llvm-project#218152 (which is now fixed).
Sunrisepeak commentedon Oct 13, 2026
Yes, mcpp added llvm 23.1.3, which fixed the issue.