diff --git a/xml/issue4264.xml b/xml/issue4264.xml
index d0d7f90fbb..a536a21285 100644
--- a/xml/issue4264.xml
+++ b/xml/issue4264.xml
@@ -14,10 +14,10 @@ Currently the wording in
-+
-2- Let t be an object of a type that is a specialization of function, copyable_function, or move_only_function, such that the target object -x of t has a type that is a specialization of function, +x of t has a type that is a specialization of function, copyable_function, or move_only_function. Each argument of the invocation of x evaluated as part of the invocation of t may alias an argument in the same position in the invocation of t that has the same type, @@ -38,6 +38,131 @@ an implementation to perform such an optimization. As a consequence, it is accep to specify the allowance for all combinations of polymorphic wrappers, even for creating an owning wrapper from a non-owning one, where implementing such an optimization may not be possible.
+ ++ + ++This wording is relative to
+. + + +
+ +- +
Modify
+ +as indicated: ++ ++-2- Let t be an object of a type that is a specialization of function, +copyable_function,
+ormove_only_function, or function_ref, +such that the target object x of t has a type that is a specialization of function, +copyable_function,ormove_only_function, or function_ref. +Each argument of the invocation of x evaluated as part of the invocation of t +may alias an argument in the same position in the invocation of t that has the same type, +even if the corresponding parameter is not of reference type. +2024-05-21; Tomasz's comment and upates proposed resolution + ++After implementing double indirection avoidance in the libstdc++, I have realized +that above wording change is insufficient to cover all user observable effects of +the change. Revelant quote from the +Avoid double indirection in function_ref from libstdc++ mailing lists: +
+ +++ ++To avoidance of double indirection requires that constructed function_ref, +refers directly to the target function of the source, instead of source, +and this is visible after the assigment: +
+ ++void foo() noexcept; +void bar() noexcept; + +std::function_ref<void() noexcept> sr(&foo); +std::function_ref<void()> dr(sr); +dr(); // calls `foo` regardless of implementation + +sr = &bar; +sr(); // calls `bar` +dr(); // still calls `foo` if we avoid indirection, + // calls `bar` if we do not ++ ++Similary for move_only_function/copyable_function source: +
+ ++std::move_only_function<void()> sm; +std::function_ref<void()> dm(sm); + +dm(); // UB because `sm` is empty + +sm = &foo; + +dm(); // remains UB if we avoid indirection, + // calls `bar` if we do not. ++ ++While we may want to allow skipping indirection for function_ref, +as this produces same behavior as in case for copy constructor (matching +signatures): +
+ ++void foo() noexcept; +void bar() noexcept; + +std::function_ref<void() noexcept> sr(&foo); +std::function_ref<void() noexcept> dr(sr); // copy-cosntructor +dr(); // calls `foo` regardless of implementation + +sr = &bar; +sr(); // calls `bar` +dr(); // still calls `foo` if we avoid indirection ++ + ++I do not think this is acceptable for move_only_function. +… +
+ ++Note that for the same reason, implementations are not free to avoid +dangling when constructing function_ref from reference_wrapper: +
+ ++auto srw = std::ref(&foo); +std::function_ref<void()> drw(srw); +drw(); // calls `foo` + +srw = std::ref(&bar); +drw(); // calls `foo` if we unwrap referenc wrapper, + // calls `bar` otherwise. ++ ++Note that this is limited to function_ref due reference nature of this +wrapper. +
+ ++The updated resolution allows indirection but making it unspecified if +function_ref constructed from other function_ref specialization, +will refer to source object or its target. +
+@@ -49,10 +174,10 @@ This wording is relative to - \ No newline at end of file +. + + Modify
as indicated: -++
-2- Let t be an object of a type that is a specialization of function, copyable_function,
ormove_only_function, or function_ref, -such that the target object x of t has a type that is a specialization of function, +such that the target object x of t has a type that is a specialization of function, copyable_function,ormove_only_function, or function_ref. Each argument of the invocation of x evaluated as part of the invocation of t may alias an argument in the same position in the invocation of t that has the same type, @@ -60,9 +185,45 @@ even if the corresponding parameter is not of reference type.+ Modify
+ +as indicated: +++template<class F> constexpr function_ref(F&&) noexcept; +++[…] ++-7- Effects: +Initializes bound-entity with addressof(f) +and thunk-ptr with the address of a function thunk such that +thunk(bound-entity, call-args...) is expression-equivalent +(
+) to +invoke_r<R>(static_cast<cv T&>(f), call-args...). + -X- Remarks: +If remove_cveref_t<F> is specialization of function_ref implementation +may initialize bound-entity with bound-entity of f. +[Example::
++void f1() noexcept; +void f2() noexcept; + +function_ref<void() noexcept> r1(&r1); +function_ref<void()> r2(r1); +r1 = &f2; +f2(); // it is unspecified if `f1` or `f2` is invoked ++— end example]
+ +