Skip to content

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

@Sunrisepeak

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.o

With 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:

  1. An exported std::align_val_t declared inside extern "C++" in a module interface.
  2. After it, the declaration of a replaceable global allocation or deallocation function, which makes clang declare the global new/delete family implicitly, std::align_val_t included.
  3. 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.hppxutilityyvals.hcrtdbg.hvcruntime_new_debug.hvcruntime_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

  1. Use clang 23.1.1 or later (or stay on 22.1.8). This is the actual fix.
  2. 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).
    • AlignedAllocation is an ordinary language option that must match between a module and its importers, so it cannot be set on std.ixx alone.
    • The semantic cost: a new expression for an over-aligned type no longer selects the std::align_val_t overloads.
    • This is what lsp-mcpp does for clangd 23.1.0; with it, clangd builds std, std.compat and 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 std module, or add workaround 2 for *-windows-msvc targets 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 ambiguous when building the MSVC STL std module; fixed in 23.1.1 (align_val_t is ambiguous under MSVC in a module llvm/llvm-project#218152); or build every unit with -fno-aligned-allocation."

Upstream

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    upstream-bug根因在上游(编译器/构建工具/依赖),mcpp 只能绕过或声明为缺口

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions