Bug: Missing `<intrin.h>` in `winrt.Windows.Foundation.ixx` in module builds
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 72/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- cpp
- Domaine
- backend, build-system
Piste de recherche
Lisez la fragment global du module dans winrt.Windows.Foundation.ixx et comparez ses inclusions avec l’utilisation de _InterlockedCompareExchangePointer dans Windows.Foundation.h. Ajoutez la déclaration de l’intrinsèque manquante à la compilation du module et compilez le module Windows.Foundation avec GCC ou Clang pour confirmer que l’erreur de recherche signalée a disparu.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Version
3.0.260818.1
Summary
In C++20 module builds (-modules), the global module fragment of winrt.Windows.Foundation.ixx does not include <intrin.h>, even though the coroutine helpers in Windows.Foundation.h (winrt::when_any) directly call _InterlockedCompareExchangePointer.
Because <intrin.h> is only included in the global module fragment of winrt_base.ixx and is not exported across modules, _InterlockedCompareExchangePointer has no visible declaration in winrt.Windows.Foundation.ixx:
- GCC and Clang (targeting MinGW) reject
winrt.Windows.Foundation.ixxduring template definition lookup. - Clang (targeting MSVC) masks this because
-fms-extensionstreats the intrinsic as a predeclared compiler builtin. - MSVC masks this only because an earlier template instantiation in
Windows.Foundation.hhappens to pull the global module fragment declaration fromwinrt_base.ifcinto scope beforewinrt::when_anyis parsed.
Here is a minimal reproducible example for the msvc compiler bug:
// hidden.h
inline int hidden(int value)
{
return value;
}
// mod.ixx
module;
#include "hidden.h"
export module provider;
export template <class T>
auto touch(T value)
{
return hidden(value);
}
// main.cpp
import provider;
int test()
{
touch(0); // Instantiating the template leaks `hidden` into scope
return hidden(42); // MSVC erroneously allows unqualified lookup to find `hidden`
}
Reproducible example
$out = Join-Path $env:TEMP "cppwinrt_intrin_repro"
Remove-Item -Recurse -Force $out -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force -Path $out | Out-Null
Push-Location $out
# 1. Generate module projection with cppwinrt 3.0.260818.1
$cppwinrt = "$env:USERPROFILE\.nuget\packages\microsoft.windows.cppwinrt\3.0.260818.1\bin\cppwinrt.exe"
& $cppwinrt -in local -out $out -modules -include Windows.Foundation
# Assume upstream fix for `export extern "C"` in winrt/base.h
# $baseH = Get-Content "winrt/base.h" -Raw
# $idx = $baseH.IndexOf('extern "C"')
# Set-Content "winrt/base.h" ($baseH.Substring(0, $idx) + 'export extern "C"' + $baseH.Substring($idx + 10))
# 2. MSVC
$vsDevCmd = "C:\Program Files\Microsoft Visual Studio\18\Community\Common7\Tools\VsDevCmd.bat"
$stdIxx = Get-ChildItem "C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\*\modules\std.ixx" |
Select-Object -Last 1 -ExpandProperty FullName
$msvcCmds = @(
"`"$vsDevCmd`" -arch=x64 -no_logo"
"cd /d `"$out`""
"cl /nologo /std:c++20 /EHsc /MD /c /interface /TP `"$stdIxx`" /ifcOutput std.ifc"
"cl /nologo /std:c++20 /EHsc /MD /I. /c /interface /TP winrt/winrt_numerics.ixx /ifcOutput winrt_numerics.ifc"
"cl /nologo /std:c++20 /EHsc /MD /I. /c /interface /TP winrt/winrt_base.ixx /reference std=std.ifc /reference winrt_numerics=winrt_numerics.ifc /ifcOutput winrt_base.ifc"
"cl /nologo /std:c++20 /EHsc /MD /I. /c /interface /TP winrt/winrt.Windows.Foundation.ixx /reference std=std.ifc /reference winrt_numerics=winrt_numerics.ifc /reference winrt_base=winrt_base.ifc /ifcOutput winrt.Windows.Foundation.ifc"
) -join " && "
cmd /c $msvcCmds
# 3. GCC
(Get-Content "winrt/winrt_numerics.ixx" -Raw) -replace '#include <intrin.h>', "#include <x86intrin.h>`n#include <algorithm>`n#include <cmath>`n#include <intrin.h>" | Set-Content "winrt/winrt_numerics.ixx"
(Get-Content "winrt/winrt_base.ixx" -Raw) -replace '#include <intrin.h>', "#include <x86intrin.h>`n#include <intrin.h>" | Set-Content "winrt/winrt_base.ixx"
$stdCc = Get-ChildItem "C:\Tools\msys64\ucrt64\include\c++\*\bits\std.cc" | Select-Object -First 1 -ExpandProperty FullName
g++ -std=c++23 -fmodules -c "$stdCc" -o std.o
g++ -std=c++23 -fmodules -I. -x c++ -c winrt/winrt_numerics.ixx -o winrt_numerics.o
g++ -std=c++23 -fmodules -I. -x c++ -c winrt/winrt_base.ixx -o winrt_base.o
g++ -std=c++23 -fmodules -I. -x c++ -c winrt/winrt.Windows.Foundation.ixx -o winrt.Windows.Foundation.o
Pop-Location
MSVC output:
std.ixx
winrt_numerics.ixx
winrt_base.ixx
winrt.Windows.Foundation.ixx
GCC output when compiling winrt/winrt.Windows.Foundation.ixx:
In file included from winrt/winrt.Windows.Foundation.ixx:102:
./winrt/Windows.Foundation.h: In member function 'void winrt::when_any(const T&, const Rest& ...)::shared_type::operator()(const T&, winrt::Windows::Foundation::AsyncStatus)':
./winrt/Windows.Foundation.h:4217:32: error: there are no arguments to '_InterlockedCompareExchangePointer' that depend on a template parameter, so a declaration of '_InterlockedCompareExchangePointer' must be available [-Wtemplate-body]
4217 | if (nullptr == _InterlockedCompareExchangePointer(reinterpret_cast<void**>(&result), sender_abi, nullptr))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
g++ version:
g++ -v
Using built-in specs.
COLLECT_GCC=C:\Tools\msys64\ucrt64\bin\g++.exe
COLLECT_LTO_WRAPPER=C:/Tools/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/16.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-16.2.0/configure --prefix=/ucrt64 --with-sysroot=/ucrt64 --with-build-sysroot=D:/M/msys64/ucrt64 --with-local-prefix=/local --with-native-system-header-dir=/include --libexecdir=/ucrt64/lib --enable-bootstrap --enable-checking=release --with-arch=nocona --with-tune=generic --enable-mingw-wildcard --enable-languages=c,c++,ada,fortran,lto,objc,obj-c++,jit --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-tls --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-backtrace=yes --enable-libstdcxx-filesystem-ts --enable-libstdcxx-time --disable-libstdcxx-pch --enable-libgomp --disable-libssp --disable-multilib --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/ucrt64 --with-mpfr=/ucrt64 --with-mpc=/ucrt64 --with-isl=/ucrt64 --with-pkgversion='Rev6, Built by MSYS2 project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as --with-gnu-ld --with-libstdcxx-zoneinfo=yes --disable-libstdcxx-debug --enable-lto --enable-plugin --with-boot-ldflags=-static-libstdc++ --with-stage1-ldflags=-static-libstdc++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 16.2.0 (Rev6, Built by MSYS2 project)
Additional comments
winrt_numerics.ixx includes <windowsnumerics.impl.h> directly inside its module purview after pre-including only <directxmath.h> in the global module fragment. However, <windowsnumerics.impl.h> transitively includes standard library headers (<stdexcept> and <limits> in the Windows SDK, and <algorithm> and <cmath> in mingw-w64) inside the module purview, which breaks module builds on libstdc++ and libc++. In addition, the DirectX interop functions (XMLoadFloat2, XMStoreFloat2, etc.) defined in <windowsnumerics.impl.h> sit outside _WINDOWS_NUMERICS_BEGIN_NAMESPACE_, leaving them unexported and attached to the winrt_numerics module even on MSVC.
- Langage dominant
- C++
- Étoiles
- 1.9k
- Forks
- 288
- Merge moyen
- 18 h 15 min
- PR mergées (30 j)
- 2
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de microsoft/cppwinrt
-
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
microsoft/cppwinrt#1554 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 45/100
microsoft/cppwinrt#1647 · 8 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Bug: Unexported `extern "C"` block in `base.h` makes `WINRT_IMPL_*` declarations invisible to downstream modulesPeut-être pris @YexuanXiao l’a pris aujourd’hui. Ouverte
Difficulté 4/5 3-5 jours Accessibilité débutants 48/100
microsoft/cppwinrt#1643 · 5 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
base_macros.h disables warnings without push/pop, leaking them into consumer translation unitsPeut-être pris @DanielJump l’a pris il y a 64 jours. Ouverte
Difficulté 1/5 Moins d'une heure Accessibilité débutants 20/100
Les mainteneurs répondent en général sous 1 jour
-
Bug: headers cannot be compiled at high warning levels (MSVC /Wall, clang)Peut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 25/100
microsoft/cppwinrt#1620 · 3 commentaires · 1 réaction ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de microsoft/cppwinrt
Issues similaires
-
bug libcudf
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
Les mainteneurs répondent en général sous 2 jours
-
level/task module/cloud monitoring type/maintenance
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
LadybirdBrowser/ladybird#13809 ·
Les mainteneurs répondent en général sous 1 jour
-
bug module:nodes tests
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
rocketride-org/rocketride-server#3020 ·
Les mainteneurs répondent en général sous 2 jours
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
Les mainteneurs répondent en général sous 9 jours