The MSVC Build Tools Preview is updated regularly with the latest features and fixes from the MSVC development team. This post covers updates from the past month, currently targeting the v14.52 release. This encompasses changes across the compiler frontend, backend, linker, standard library, and related tools.
Although you can acquire the MSVC Build Tools Preview through either the Visual Studio 2026 Stable Channel or Insiders Channel, Insiders gets MSVC Preview updates more quickly (roughly weekly).
To check if it is installed simply make sure one or both of these components are checked in the installer:
- MSVC Build Tools for x64/x86 (Preview)
- MSVC Build Tools for ARM64/ARM64EC (Preview)
Follow the instructions on https://aka.ms/msvc/preview to configure your IDE & command prompts to use the MSVC Build Tools Preview.
The version number printed by cl.exe and link.exe will be at least 19.52.36520 / 14.52.36520.
We appreciate any feedback that you may have. Please report any issues on Visual Studio Developer Community so we can address them by the time we move out of preview.
C++ Conformance and Frontend
- Relaxed the rules for designated initialization to accept more valid C++ code.
- Added support for
constexprnew[](array allocation) inside modules. - Corrected comparison of non-type template arguments so that constraints (concepts) no longer cause external member function definitions to fail to compile.
- Fixed type deduction so the correct type is propagated through nested lambdas, including
decltypeof a captured entity inside a non-mutable lambda. - Fixed an incorrect result from the
__is_constructibletype trait. - Fixed a false negative from
std::is_layout_compatibleon structs containing nested structs. - Improved
_Pragmahandling: better support when mixed with macros, full support under/E, and fixes for preprocessor crashes when a function-like macro expands at a_Pragma. - Increased the compiler limit for deeply nested initializers and increased the maximum size of legacy preprocessor macro buffers.
- Reduced memory usage when caret (
^) diagnostics are enabled. - Fixed selection of an overloaded member function via
static_castwhen the member has a deduced (auto) return type in a class template. - Fixed template-argument deduction for class templates that previously produced a spurious
C2641. - Fixed several internal compiler errors, including those involving
requireswith a default template argument before a parameter pack, coroutines with aggregate initialization, and recursive variadic template default member initializers. - Improved robustness of
MultiByteToWideCharhandling on older Windows versions.
C++ Modules
- Fixed a
fatal error C1001andC1116regression when importing a partitioned C++23 module (built withimport std;) after including third-party headers. - Fixed an internal compiler error when exporting an overload set from a module.
- Improved header-unit resolution so a quoted include correctly falls back to an angle-bracket lookup when the resolved entry was already consumed.
- Added a new
LNK4321warning that diagnoses duplicate C++ module exports in an import library.
Code Generation and Optimization
ARM64 improvements:
- Added vectorization support for
floor,ceil,trunc, andround. - Improved NEON code generation: folded redundant duplicate sequences, eliminated redundant compare-against-zero on mask inputs, and tracked live bits across NEON vector arithmetic to remove dead instructions.
- Enabled load-pair/store-pair fusion for adjacent global table lookups accessed through a computed index.
- Improved register spill and rematerialization cost modeling for high-use values.
- Fixed a signedness mismatch in paired integer-to-floating-point SIMD conversions.
x64 improvements:
- Extended code generation for the newest x64 instruction set (APX), including new destination-form lowering and a conditional-move optimization pattern, and fixed keeping caller-saved registers unnecessarily live across calls under LTCG.
- Fixed generation of an invalid AVX-512 gather instruction that used a high vector index register.
- Improved code generation for population-count (
popcount) patterns. - Preserved the sign of negative zero in the 32-bit x86
floorexpansion. - Fixed a miscompilation of descending bit-search loops that use trailing-zero counting.
- Addressed a performance regression in a speech-recognition workload involving fused multiply-add.
Optimizer:
- Enabled strength reduction for induction variables that can overflow, and expanded the set of overflow cases the optimizer can handle safely.
- Enabled earlier loop-invariant code motion.
- Enabled a new expression-reassociation pass.
- Enabled type-based devirtualization alongside PGO and improved speculative devirtualization inlining.
- Improved heuristics leading to more common-subexpression elimination in larger functions.
- Fixed several optimizer internal compiler errors and miscompilations, including a jump-threading crash, loop unswitching under LTCG, preservation of overflow semantics through the loop optimizer, a hang in string-compare simplification, and incorrect code generation for indirection through a based pointer.
- Fixed a fence-preservation issue under
/fp:strict.
Other code generation:
- Fixed
/LTCG:incrementalunnecessarily falling back to a full compilation on alternating links. - Added a graceful bailout when profile data cannot be read for a mixed
/Od+/O2LTCG build. - Emit
C4744forexterntype mismatches under LTCG.
Linker
- Fixed a linker crash during incremental pointer calculation.
- Fixed incremental linking when the
/NOEXPoption is used. - Reduced PDB file size growth in incremental-link scenarios.
- Improved determinism by masking the PDB age in the PE hash computation.
Static Analysis
- Added command-line options to configure environment variables for Code Analysis.
- Fixed several Code Analysis crashes, including one involving
throwin a ternary operator.
AddressSanitizer
- Fix in ASan interception of
RtlReAllocateHeap, preventing crashes when re-allocating ASan-owned memory during process termination.
STL
- See https://github.com/microsoft/STL/wiki/Changelog for details on STL improvements in the MSVC Build Tools Preview.
Tickets Fixed
The following tickets reported through Developer Community have been fixed in this update:
- /LTCG:incremental falls back to full compilation every second time when nothing is changed, due to supposed IPDB IOBJ mismatch
- APX LTCG codegen keeps caller-saved registers live across calls
- ARM64 codegen is breaks function scope try/catch when the function is marked noexcept
- ARM64 codegen: paired int->double SIMD conversion emits USHLL+UCVTF instead of SSHLL+SCVTF; negative ints become ~4.29e9 doubles
- ARM64 LTCG c2 ICE C1001 “Illegal reg field” causes LNK1257
- Arm64 MSVC misses optimization opportunity by not fusing two ldrs to ldp
- ARM64EC linker emits LNK4279 for __imp_PtInRect icall thunk mismatch
- AVX optimizer/codegen bug
- Bug: Calling FileSavePicker::FileTypeChoices::Insert throws an exception with C++/WinRT 3.0 modules.
- C++ Code Analysis crashes with SEH, std::span and initializer_list
- C++ Modules compiler hits fatal error C1001 compiling .ixx files
- C2440: static_cast to select an overloaded member function with a deduced (auto) return type fails in a class template
- CHPE /d2hybrid:emit_guest_references causes ICE
- cl.exe 19.51 Regression: Miscompiles Plain Code
- cl.exe fatal error C1001 and exit 0xE06D5034
- Compiler crashes with optimization O2 when calling _hypot in 17.14.21
- Concepts cause external member function definition to fail to compile
- consteval causes C1054: compiler limit: initializers nested too deeply initializing tuple
- fatal error C1001: Internal compiler error
- fatal error LNK1000: Internal error during 14.51 MSVC toolset test
- ICE linking binary with LTCG when specifying /Od for some of the objs
- ICE preprocessing file with
_Pragma. - Incorrect AVX codegen in MSVC 14.50+ under specific circumstances
- Incorrect type is passed through nested lambdas
- Increase compiler limit for nested initializers (fatal error C1054)
- Incremental linking is broken when using the -noexp flag with link.exe
- Internal Compiler Error when struct implicitly converted to bool
- LNK4279 icall thunk mismatch on ARM64EC with std::filesystem::path and std::chrono::tzdb
- LNK4279 warning when building ARM64EC projects with VS2026 18.6.0 Compiler 19.51
- LTCG back end 14.51 misorders PS_ASSERT(FALSE) before call on AMD64/ARM64
- Microsoft Analyzer crashes with fatal error C1001 on throw in ternary operator
- MSVC /O2 triggers fatal error C1001 with function named gsl::details::terminate
- MSVC 14.51 C7658 rejects array variable as non-type template argument (‘the initializer must be the address of a variable or function’)
- MSVC 14.51 codegen: ternary picks wrong =default constructed branch for std::string class
- MSVC AVX-512 emits invalid EVEX vpgatherdd with high ZMM index register
- MSVC C1001 compiling C++20 operator<=> with conditional strong_ordering (cl 19.51)
- MSVC calculates an incorrect result of __is_constructible
- MSVC cl.exe hangs compiling some Unreal Engine 5 source files
- MSVC CL.exe Release build hits internal compiler error in plutovg-font.c
- MSVC coroutines ICE C1001 on aggregate init with shared_ptr field
- MSVC ICE in PackExpander.cpp with requires default template argument before parameter pack
- MSVC member template out-of-class definition rejected with C2244/C2131
- MSVC modules: fatal error C1116 importing a partitioned C++23 module (compiled with
import std;) after#includeing asio - MSVC out-of-class conversion operator misbinds Transform, C2976/C7753
- MSVC preprocessor crashes on function-like macro expanded at _Pragma
- MSVC recursive variadic template NSDMI lambda misfires C3482/C2951
- MSVC rejects nested lambda decltype(lambda expression)::type alias in using declaration
- MSVC v14.51 Linker Crash in IncrCalcPtrs
- range-based for variables can be shadow by loop’s block scope
- std::generator fails to compile for 32-bit x86 with /guard:cf with error C4737
- Type trait std::is_layout_compatible returns false negative when used on struct with nested structs
- VS2026 18.2 generates incorrect IL when inlining template function pointer calls in C++/CLI virtual destructors
- VS2026 VC14.50 c++/cli /O2 Common Language Runtime detected an invalid program error
- VSInstr/CodeCoverage.Console misinstrument switch tables, hang or crash
Try Out the MSVC Build Tools Preview!
Please try out the MSVC Build Tools Preview and let us know what you think! Installation instructions:
- Download Visual Studio 2026 Insiders for frequent updates, or download Visual Studio 2026 for less frequent updates.
- Install the Desktop development with C++ workload and make sure one or both of these MSVC components are checked (depending on your target build architecture):
- MSVC Build Tools for x64/x86 (Preview)
- MSVC Build Tools for ARM64/ARM64EC (Preview)
- Follow the instructions on https://aka.ms/msvc/preview on configuring your IDE & command prompts to use the MSVC Build Tools Preview.
- Share your feedback with us on Visual Studio Developer Community.
Thanks for the updates!
Some feedback to be passed down, if I may - when tickets from developercommunity (like this one: LNK4279 icall thunk mismatch on ARM64EC with std::filesystem::path and std::chrono::tzdb) get marked as "Fixed in Visual Studio 18.8.0", can they please also get marked *which toolset* the fix is actually in? It seems this fix is in the preview toolset that is released alongside 18.8.0 - so I guess the marking is technically correct - but it doesn't help me because it's not fixed in any of the production toolsets.
I think this is doubly more important now with the pace...