Bug: GCC warns about breaking strict-aliasing rules for 32-bit builds
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 55/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 冷清
- 技术栈
- cmake, cpp
调研方向
从提供的 CMakeLists.txt 和 test.cpp 开始,使用 GCC 14.2 构建可复现的 x86 Release 示例。检查 winrt/base.h 和 winrt/Windows.Foundation.h 中报告的 strict-aliasing 警告,同时包含 _WIN64 分支以进行比较。当示例在保留现有行为的同时能够无这些警告地完成构建时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
Version
v2.0.250303.1
Summary
When I build my project for x86 (32-bit) with GCC 14.2.0 (MSYS2) in release mode, I get warnings dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] for winrt/base.h:
[...]winrt/base.h: In member function 'void winrt::impl::factory_cach
e_entry_base::clear()':
[...]winrt/base.h:6357:86: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6357 | int64_t const result = _InterlockedCompareExchange64((int64_t*)this, 0, *(int64_
t*)¤t_value);
[...]winrt/base.h:6359:28: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6359 | if (result == *(int64_t*)¤t_value)
[...]winrt/Windows.Foundation.h:173:43: warning: dereferencing type-p
unned pointer will break strict-aliasing rules [-Wstrict-aliasing]
173 | auto const _winrt_abi_type = *(abi_t<winrt::Windows::Foundation::IAsyncInfo>**)&
_winrt_casted_result;
[...]winrt/Windows.Foundation.h:2498:102: warning: dereferencing type
-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
2498 | (*this)(*reinterpret_cast<winrt::Windows::Foundation::IAsyncAction const*>(&asyn
cInfo), *reinterpret_cast<winrt::Windows::Foundation::AsyncStatus const*>(&asyncStatus));
The problematic code in base.h is:
#if defined _WIN64
#if defined(__GNUC__)
bool exchanged = __sync_bool_compare_and_swap((__int128*)this, *(__int128*)¤t_value, (__int128)0);
#else
bool exchanged = 1 == _InterlockedCompareExchange128((int64_t*)this, 0, 0, (int64_t*)¤t_value);
#endif
if (exchanged)
{
pointer_value->Release();
}
#else
int64_t const result = _InterlockedCompareExchange64((int64_t*)this, 0, *(int64_t*)¤t_value);
if (result == *(int64_t*)¤t_value)
{
pointer_value->Release();
}
#endif
Unlike base.h, the problematic code from Windows.Foundation.h doesn't seem to be architecture-specific (no _WIN64 and other macros).
Reproducible example
Save the following CMakeLists.txt and test.cpp to the same directory and run:
cmake -DCMAKE_BUILD_TYPE=Release -DWINRT_INCLUDE_DIR=<your-path-here> -B build
cmake --build build
CMakeLists.txt:
cmake_minimum_required(VERSION 3.22)
project(test)
add_executable(test test.cpp)
set_target_properties(
test PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(test PRIVATE -Wall -Wextra -pedantic)
endif()
target_include_directories(test PRIVATE "${WINRT_INCLUDE_DIR}")
target_link_libraries(test PRIVATE windowsapp)
test.cpp
#include <winrt/base.h>
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Foundation.h>
using namespace winrt::Windows::ApplicationModel;
int main()
{
auto startupTask = StartupTask::GetAsync(L"id").get();
}
The full output in my case is:
[1/2] Building CXX object CMakeFiles/test.dir/test.cpp.obj
In file included from [...]/test/test.cpp:1:
[...]/include/winrt/base.h: In member function 'void winrt::impl::factory_cach
e_entry_base::clear()':
[...]/include/winrt/base.h:6357:86: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6357 | int64_t const result = _InterlockedCompareExchange64((int64_t*)this, 0, *(int64_
t*)¤t_value);
| ^~~~~~~
~~~~~~~~~~~~~~~~~
[...]/include/winrt/base.h:6359:28: warning: dereferencing type-punned pointer
will break strict-aliasing rules [-Wstrict-aliasing]
6359 | if (result == *(int64_t*)¤t_value)
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from [...]/test/test.cpp:3:
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'auto winrt::imp
l::consume_Windows_Foundation_IAsyncInfo<D>::Status() const [with D = winrt::Windows::Foundation::IA
syncAction]':
[...]/include/winrt/Windows.Foundation.h:5133:35: required from 'auto winrt:
:impl::wait_get(const Async&) [with Async = winrt::Windows::Foundation::IAsyncAction]'
5133 | auto status = async.Status();
| ~~~~~~~~~~~~^~
[...]/include/winrt/Windows.Foundation.h:5261:23: required from here
5261 | impl::wait_get(static_cast<Windows::Foundation::IAsyncAction const&>(static_cast<D c
onst&>(*this)));
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h:173:43: warning: dereferencing type-p
unned pointer will break strict-aliasing rules [-Wstrict-aliasing]
173 | auto const _winrt_abi_type = *(abi_t<winrt::Windows::Foundation::IAsyncInfo>**)&
_winrt_casted_result;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'auto winrt::imp
l::consume_Windows_Foundation_IAsyncInfo<D>::Status() const [with D = winrt::Windows::Foundation::IA
syncOperation<winrt::Windows::ApplicationModel::StartupTask>]':
[...]/include/winrt/Windows.Foundation.h:5133:35: required from 'auto winrt:
:impl::wait_get(const Async&) [with Async = winrt::Windows::Foundation::IAsyncOperation<winrt::Windo
ws::ApplicationModel::StartupTask>]'
5133 | auto status = async.Status();
| ~~~~~~~~~~~~^~
[...]/include/winrt/Windows.Foundation.h:5272:30: required from 'auto winrt:
:impl::consume_Windows_Foundation_IAsyncOperation<D, TResult>::get() const [with D = winrt::Windows:
:Foundation::IAsyncOperation<winrt::Windows::ApplicationModel::StartupTask>; TResult = winrt::Window
s::ApplicationModel::StartupTask]'
5272 | return impl::wait_get(static_cast<Windows::Foundation::IAsyncOperation<TResult> cons
t&>(static_cast<D const&>(*this)));
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[...]/test/test.cpp:11:56: required from here
11 | auto startupTask = StartupTask::GetAsync(L"id").get();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
[...]/include/winrt/Windows.Foundation.h:173:43: warning: dereferencing type-p
unned pointer will break strict-aliasing rules [-Wstrict-aliasing]
173 | auto const _winrt_abi_type = *(abi_t<winrt::Windows::Foundation::IAsyncInfo>**)&
_winrt_casted_result;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'int32_t winrt::
impl::delegate<winrt::Windows::Foundation::AsyncOperationCompletedHandler<TResult>, H>::Invoke(void*
, int32_t) [with H = winrt::impl::wait_for_completed<winrt::Windows::Foundation::IAsyncOperation<win
rt::Windows::ApplicationModel::StartupTask> >(const winrt::Windows::Foundation::IAsyncOperation<winr
t::Windows::ApplicationModel::StartupTask>&, uint32_t)::shared_type; TResult = winrt::Windows::Appli
cationModel::StartupTask; int32_t = int]':
[...]/include/winrt/Windows.Foundation.h:2529:27: required from here
2529 | int32_t __stdcall Invoke(void* asyncInfo, int32_t asyncStatus) noexcept final try
| ^~~~~~
[...]/include/winrt/Windows.Foundation.h:2531:114: warning: dereferencing type
-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
2531 | (*this)(*reinterpret_cast<winrt::Windows::Foundation::IAsyncOperation<TResult> c
onst*>(&asyncInfo), *reinterpret_cast<winrt::Windows::Foundation::AsyncStatus const*>(&asyncStatus))
;
|
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[...]/include/winrt/Windows.Foundation.h: In instantiation of 'int32_t winrt::
impl::delegate<winrt::Windows::Foundation::AsyncActionCompletedHandler, H>::Invoke(void*, int32_t) [
with H = winrt::impl::wait_for_completed<winrt::Windows::Foundation::IAsyncAction>(const winrt::Wind
ows::Foundation::IAsyncAction&, uint32_t)::shared_type; int32_t = int]':
[...]/include/winrt/Windows.Foundation.h:2496:27: required from here
2496 | int32_t __stdcall Invoke(void* asyncInfo, int32_t asyncStatus) noexcept final try
| ^~~~~~
[...]/include/winrt/Windows.Foundation.h:2498:102: warning: dereferencing type
-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
2498 | (*this)(*reinterpret_cast<winrt::Windows::Foundation::IAsyncAction const*>(&asyn
cInfo), *reinterpret_cast<winrt::Windows::Foundation::AsyncStatus const*>(&asyncStatus));
|
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2/2] Linking CXX executable test.exe
Expected behavior
No response
Actual behavior
No response
Additional comments
I haven't tried compiling for 64 bit, but it's possible that similar warnings would appear in that case (in particular, the code in base.h intended for _WIN64 uses similar pointer dereferencing).
- 主要语言
- C++
- 星标
- 1.9k
- 派生
- 281
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/cppwinrt 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
microsoft/cppwinrt#1554 · 2 条评论 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 20/100
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 25/100
microsoft/cppwinrt#1620 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 48/100
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 30/100
microsoft/cppwinrt#1610 · 3 条评论 · 2 个 reaction ·
维护者通常 1 天内回复
查看 microsoft/cppwinrt 的全部 Issue
相似的 Issue
-
upstream update
难度 2/5 1-3 小时 新手友好度 75/100
conan-io/conan-center-index#31098 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 86/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 2 天内回复
-
bug chart-audit
难度 1/5 1 小时以内 新手友好度 92/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100
godotengine/godot#124120 ·
维护者通常 1 天内回复