-
Notifications
You must be signed in to change notification settings - Fork 0
Comparing changes
Open a pull request
base repository: Security-Testing-Five/cppwinrt
base: master
head repository: microsoft/cppwinrt
compare: master
- 7 commits
- 20 files changed
- 11 contributors
Commits on Jul 8, 2026
-
Fix C4819 warning: replace non-ASCII em dash in base_macros.h comment (…
…microsoft#1606) * Initial plan * Fix C4819 warning: replace non-ASCII em dash with ASCII hyphen in base_macros.h comment --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for a535d38 - Browse repository at this point
Copy the full SHA a535d38View commit details
Commits on Jul 27, 2026
-
Fix race condition in cancellation setup/teardown (microsoft#1609)
The code failed to handle three cases. 1. A cancellation is in progress when a cancellable awaitable begins. 2. A cancellation is in progress when a cancellable awaitable ends. 3. A cancellation is in progress when a cancel() request is made. The m_canceller member has one of these three values: * nullptr, meaning that there is nothing to cancel. It has this value when the coroutine is not awaiting, or if it is awaiting something that cannot be cancelled. * cancelling_ptr, meaning that another thread (not the coroutine thread) is in the middle of cancellation request. * function pointer, representing the function to call to cancel the await. In case 1, we should not overwrite the canceling_ptr with the function pointer, because only the code doing the cancel() can transition into/out of cancelling_ptr. In case 2, we intended to spin until the m_canceller is no longer cancelling_ptr, but we used m_canceller.exchange(nullptr) in a loop, which means that if m_canceller was cancelling_ptr, we overwrite it with nullptr. As a result, the "while" loop always exits after one iteration. We need to spin on the m_canceller without modifying it if it is cancelling_ptr. In case 3, cancel() function resets m_cancelling back to nullptr, even if the value was cancelling_ptr on entry, prematurely declaring that the existing cancel() has completed. If the original value was cancelling_ptr, we should leave it that way. There are still other cases not handled: * Coroutine already cancelled when a co_await starts. In this case, we never call the canceller, so the coroutine fails to propagate cancellation. This will require a broader fix, so I'm not going to fix it in this PR. This PR is primarily about fixing the crash caused by case 2. Cases 1 and 3 were fixed opportunistically.
Configuration menu - View commit details
-
Copy full SHA for d3d92d7 - Browse repository at this point
Copy the full SHA d3d92d7View commit details
Commits on Jul 28, 2026
-
Add <ratio> header to base_includes.h (microsoft#1612)
base_types.h uses std::ratio_multiply, which is defined in <ratio>. Under strict include-what-you-use rules not referencing this header can lead to weird build breaks.
Configuration menu - View commit details
-
Copy full SHA for d6cff31 - Browse repository at this point
Copy the full SHA d6cff31View commit details
Commits on Aug 19, 2026
-
Remove WINRT_EXPORT in Component.g.cpp (microsoft#1597)
Co-authored-by: Ryan Shepherd <ryansh@microsoft.com>
Configuration menu - View commit details
-
Copy full SHA for a7f0233 - Browse repository at this point
Copy the full SHA a7f0233View commit details
Commits on Aug 24, 2026
-
C++/WinRT ABI interop improvements (microsoft#1608)
* Add _hs literal for compile-time fast-pass HSTRING Passing a wide string literal to a WinRT API that takes an hstring runs wcslen and fills a seven-field HSTRING_HEADER on the stack on every call (via param::hstring -> create_hstring_on_stack). For a literal, all of that is knowable at compile time and only needs to happen once. Add a `_hs` user-defined literal that builds the fast-pass reference header as a constexpr static, so `L"value"_hs` reduces to a single pointer load at the call site with no per-call wcslen or header fill. The literal-operator-template is keyed on the characters themselves via a C++20 non-type template parameter (hstring_literal_storage<N>), so each distinct literal gets its own static header with static lifetime. It returns a non-owning winrt::hstring_reference (a plain winrt::hstring would assert/free the reference header in its destructor). A matching param::hstring constructor lets the result bind to projected setters in a single user-defined conversion. A bare `param::hstring(wchar_t const(&)[N])` overload is deliberately not added: it would also bind non-literal arrays (e.g. a partially-filled wchar_t buf[260]) and infer length N-1 past the null, silently corrupting; and a runtime constructor cannot produce a content-specific static anyway. `_hs` is the explicit, safe opt-in; bare literal calls keep their unchanged wcslen path. Gated on __cpp_nontype_template_args >= 201911L. Tested under C++20 in test_cpp20/hstring_literal.cpp; the non-gated types build under C++17. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 83914e59-f7cd-4284-ad4b-4cb7b79f28c1 * Add make_ready for pre-completed async operations Returning an already-available value through an async-typed API (a cache hit, a fast path, or an API async-typed only for interface uniformity) still pays the full coroutine cost when written as `co_return value`: a heap-allocated coroutine frame plus a promise that is a complete COM object implementing IAsyncOperation and IAsyncInfo, carrying a slim_mutex, an agile completed-handler slot, an atomic status, and cancel machinery, all built and torn down on every call. Add winrt::make_ready<T>(value) and winrt::make_ready() that return a minimal already-completed IAsyncOperation<T> / IAsyncAction: it holds just the value with a fixed Completed status and no coroutine frame, no slim_mutex, no handler slot, and no cancel machinery. Setting a Completed handler on it invokes immediately, and Status()/GetResults() satisfy both the .get() and co_await consumer paths, so it is a drop-in for the synchronous-result case. `co_return` remains correct for genuinely suspending work, where the frame is doing real work and the overhead is amortized to noise. The one-shot Completed assignment is guarded with a lock-free atomic flag rather than a lock. Tested in test/make_ready.cpp. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 83914e59-f7cd-4284-ad4b-4cb7b79f28c1 * Buffer range-for iteration over non-GetAt collections Range-for over a collection that lacks GetAt (a plain IIterable<T>, or a map yielding IKeyValuePair) drove the projected IIterator one element per ABI crossing via Current/MoveNext. For a large sequence that is one vtable call per item. Route that path through a buffered_iterator that pulls a block of elements with a single IIterator::GetMany call into a small stack buffer and yields from it, refilling only when the buffer is drained. Existing `for (auto&& x : v)` code gets the speedup with no source change. The block is sized like windows-rs' BufferedIterator -- clamp(2048 / sizeof(T), 1, 128) -- to cap the buffer near 1-2 KB and bound over-fetch for large element types. Only the non-GetAt path changes. Collections with GetAt (IVector, IVectorView) keep the existing random-access fast_iterator, so no iterator-category guarantees are affected. The iterator is single-pass, matching IIterator's own semantics. Tested in test/buffered_iterator.cpp (multi-block, block boundary, empty, and a non-trivial element type). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 83914e59-f7cd-4284-ad4b-4cb7b79f28c1 * Perfect-forward make_ready value Use TResult&& + decay_t<TResult> so make_ready forwards its argument into the operation instead of taking it by value, saving a move and matching the make_unique/make_shared idiom. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 83914e59-f7cd-4284-ad4b-4cb7b79f28c1 * Make _hs a constant expression Move the fast-pass header from a function-local static into an inline constexpr variable template and mark hstring_reference and the operator constexpr, so `constexpr auto s = L"x"_hs;` is a genuine compile-time construction rather than per-call work. Add a constexpr construction to the test to prove it. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 83914e59-f7cd-4284-ad4b-4cb7b79f28c1 * Box scalars locally instead of via combase PropertyValue box_value on a scalar routed through the cached Windows.Foundation. PropertyValue activation factory into combase, which allocates a general IPropertyValue carrying the discriminated-union machinery for all property types. For the common scalar cases that round-trip is pure overhead. Point the scalar reference_traits (u8..u64, float, double, bool, char16, hstring, guid) at the in-process impl::reference<T> that already backs non-scalar IReference<T>, and make that type a correct IPropertyValue: report the right PropertyType per T (was always OtherType), fix IsNumericScalar (was true for bool), and return the value from the matching typed getter (GetString/GetGuid/GetBoolean/GetChar16/GetSingle/GetDouble previously threw). Mismatched numeric getters keep combase-style conversion (GetInt16 on a boxed int32 converts), so consumers see the same behavior minus the combase hop. This mirrors windows-rs' StockReference. Composite/array/inspectable cases (DateTime, TimeSpan, Point, Size, Rect, IReferenceArray, IInspectable) stay on combase PropertyValue. Two honest deltas vs combase, both matching windows-rs: GetRuntimeClassName is now the IReference`1<T> name rather than Windows.Foundation. PropertyValue, and cross-process the value marshals as an IReference proxy rather than by value. Tested in test/reference_boxing.cpp. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 83914e59-f7cd-4284-ad4b-4cb7b79f28c1 * Marshal boxed scalars by value via combase PropertyValue The in-proc scalar reference<T> introduced in the prior commit is agile via the free-threaded marshaler, so cross-process it marshals by reference (an IReference proxy) rather than by value the way combase PropertyValue does. Mirror windows-rs and combase: for the stock scalar types, mark reference<T> non_agile and supply IMarshal from query_interface_tearoff by lazily building the equivalent combase PropertyValue and delegating marshaling to it, so the destination materializes a real PropertyValue copy. IAgileObject is still advertised (the reference is immutable and thread-safe) to keep the agile fast path. The combase hop is paid only on marshal, never on box_value/unbox_value. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Box DateTime, TimeSpan, and Point in-process too Extend the in-proc reference<T> to cover DateTime, TimeSpan, and Point: report the correct PropertyType, return the value from the matching typed getter, and mark them stock so they still marshal by value through combase PropertyValue. Drop their combase reference_traits specializations so box_value routes to the local reference<T> like the other scalars. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Buffer range-for over GetAt collections (batch IVector via GetMany) fast_iterator (used for random-access, GetAt-capable collections like IVector/ IVectorView) now prefetches a block with a single GetMany call and serves in-window reads from it, so range-for crosses the ABI ~once per block instead of one GetAt per element. Random access is preserved: an out-of-window index re-anchors the block, and an at/after-end index defers to GetAt so E_BOUNDS behavior is unchanged. Elements are copied out (no move-out) so an index may be read repeatedly, as the random-access contract requires. This extends the non-GetAt buffering to vectors, closing the IterateVector gap to windows-rs. * Fix MSVC and clang-cl build breaks from the interop fast paths Three portability breaks surfaced by CI across MSVC and clang-cl: - Iterator batching assumed every collection/iterator has GetMany and every element type is default-constructible. IBindableVectorView has GetAt but no GetMany, IBindableIterator has no GetMany, and types like JsonValue have no default constructor. Gate the GetMany block buffer on both a GetMany detector and default-constructibility (can_batch); otherwise fall back to per-element GetAt / Current+MoveNext. The block buffer is elided entirely when unused. - reference<T>::query_interface_tearoff called .as<IMarshal>() on a dependent expression; clang requires .template as<IMarshal>(). - hstring_reference::m_handle is only read via layout punning in get_abi, so clang -Werror,-Wunused-private-field rejected it. Mark it [[maybe_unused]]. Verified: msbuild cppwinrt + test/test_old (MSVC) and test/test_nocoro/test_old (clang-cl), x64 Debug, all build clean. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Add optional clang compiler arg to build_test_all.cmd build_test_all.cmd only built the MSVC toolset, so a local pass did not catch clang-cl -Werror breaks that CI's clang-cl leg rejects. Add an optional 5th positional arg (default msvc); pass clang/clang-cl to append Clang=1,PlatformToolset=ClangCl to the cppwinrt.sln compiler and test builds, matching CI. natvis and NugetTest.sln stay on MSVC, as the clang CI leg does not cover them. Also fix a stray trailing quote on the nuget restore line and document the arg in README. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Guard _hs test's literals using-directive for non-conforming NTTP compilers hstring_literal.cpp had an unconditional using-directive for winrt::literals, but that namespace and its operator ""_hs only exist under __cpp_nontype_template_args >= 201911L. clang-cl reports 201411L (no class-type NTTP), so the namespace is absent and the using-directive failed to compile ("expected namespace name"), breaking the clang-cl test_cpp20 leg. Move the using-directive inside the same feature guard the rest of the test already uses. Verified: full CI test-project set builds clean on both MSVC v145 and clang-cl, x64 Debug. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Remove buffered-iterator and ready-async helpers Drop the batched range-for iterator (base_iterator.h) and the already-completed make_ready/ready_async async helpers (base_coroutine_foundation.h), reverting both headers to their base state. These will be reintroduced in wil/cppwinrt.h. Removes the buffered_iterator.cpp and make_ready.cpp tests accordingly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Simplify reference_base_t and test in-proc agility Collapse reference_base_t to a single implements<> whose trailing marker is conditional (non_agile for stock scalars, an inert marker placeholder otherwise), instead of duplicating the interface list across a conditional_t. implements<> ignores non-interface, non-marker type parameters, so the placeholder is a no-op. Add a test that boxes a scalar in one STA and fetches it from another via the Global Interface Table, asserting the object identity is preserved - proving the IAgileObject in-proc fast path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Box arrays locally and address review feedback Add an in-process reference_array<T> (IReferenceArray<T> + IPropertyValue), the array counterpart to reference<T>, so box_value/unbox_value of the stock array element types no longer builds a combase PropertyValue. hstring, TimeSpan, DateTime (projected type != ABI) and IInspectable/Size/Rect stay on combase. Collapse every IPropertyValue getter on both types into one internal get_as<To>() that holds the constexpr type check and throw, and share a scalar_property_type<T>()/array_property_type<T>() helper. Also fold in the earlier review fixes: single implements<> with a conditional trailing marker for reference_base_t, GetSize/GetRect fast paths, an _hs null-termination static_assert, and drop the duplicate test_module_lock_none build in build_test_all.cmd. Extend reference_boxing.cpp with array boxing, array marshal-by-value, and cross-STA agile identity coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Share a producer base, drop comments and build-script changes Fold the duplicated IPropertyValue getters and IMarshal tearoff shared by reference<T> and reference_array<T> into a reference_producer CRTP base; the two leaves just supply storage, get_as, and create_property_value. Same codegen and per-instance footprint as the two-template version, ~80 fewer source lines. Per review feedback, strip the newly-added implementation comments from base_reference_produce.h and base_string.h, and revert the build_test_all.cmd compiler-selection helper and its README note so this PR carries only the projection/boxing functionality. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: Jon Wiswall <18537118+jonwis@users.noreply.github.com> Copilot-Session: 83914e59-f7cd-4284-ad4b-4cb7b79f28c1Configuration menu - View commit details
-
Copy full SHA for 74a13c5 - Browse repository at this point
Copy the full SHA 74a13c5View commit details
Commits on Aug 26, 2026
-
Add get_unchecked() to async operations (microsoft#1565)
* Add get_only_safe_from_non_presenting_sta() to async operations Add a peer to .get() on IAsyncAction, IAsyncOperation, IAsyncActionWithProgress, and IAsyncOperationWithProgress that skips the _DEBUG-only STA blocking assert. The existing .get() asserts !is_sta_thread() to guard against blocking UI threads. However, not all STAs are UI threads — some never present UI, haven't presented yet, or never will. The assert is also _DEBUG-only, making it invisible to codebases that don't build with _DEBUG (e.g. the Windows OS). The new method get_only_safe_from_non_presenting_sta() is functionally identical to .get() but omits the STA check. The intentionally long name communicates the risk to callers. Changes: - strings/base_coroutine_foundation.h: Add wait_get_bypass_sta_check() impl helper and get_only_safe_from_non_presenting_sta() for all 4 async consume templates - cppwinrt/code_writers.h: Add declaration to generated code for all 4 async types - test/test_nocoro: Add test calling the new method from an STA thread using a real WinRT async operation (PathIO::ReadTextAsync on C:\Windows\win.ini) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename STA bypassing async get method Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix STA test cleanup and assertions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Chris Guzak (WINDOWS) <chrisg@ntdev.microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for 9cf9564 - Browse repository at this point
Copy the full SHA 9cf9564View commit details -
Configuration menu - View commit details
-
Copy full SHA for 856eaff - Browse repository at this point
Copy the full SHA 856eaffView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff master...master