[libcxx-commits] [libcxx] [libc++] Fix ill-formed return in function_ref's static-call path (PR #228868)

Yanzuo Liu via libcxx-commits libcxx-commits at lists.llvm.org
Sun Oct 4 05:51:36 PDT 2026


================
@@ -106,7 +106,10 @@ class function_ref<_Rp(_ArgTypes...) _LIBCPP_FUNCTION_REF_CV noexcept(__is_noexc
     using _Dn = remove_cv_t<_Tp>;
     if constexpr (__statically_callable<_Dn, __arg_t<_ArgTypes>...>) {
       __call_ = [](__storage_t, __arg_t<_ArgTypes>... __args) static noexcept(__is_noexcept) -> _Rp {
-        return _Dn::operator()(std::forward<__arg_t<_ArgTypes>>(__args)...);
+        if constexpr (is_void_v<_Rp>)
+          _Dn::operator()(std::forward<__arg_t<_ArgTypes>>(__args)...);
+        else
+          return _Dn::operator()(std::forward<__arg_t<_ArgTypes>>(__args)...);
----------------
zwuis wrote:

`static_cast` performs explicit conversions. It is possible for `From` to be implicitly convertible to `To` but not explicitly convertible. E.g.

```cpp
struct From;
struct To {
    explicit To(From) = delete;
};
struct From {
    operator To();
};

static_assert(std::is_convertible_v<From, To>);
static_assert(not std::convertible_to<From, To>);
```

This example comes from <https://stackoverflow.com/questions/62644070/differences-between-stdis-convertible-and-stdconvertible-to-in-practice/62644127#62644127>.

https://github.com/llvm/llvm-project/pull/228868


More information about the libcxx-commits mailing list