https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104606

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ppalka at gcc dot gnu.org

--- Comment #20 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #13)
> (In reply to Andrew Pinski from comment #5)
> > (In reply to Jakub Jelinek from comment #4)
> > > Just wild guess, perhaps the PR98842 changes between 11.1 and 11.2?
> > 
> > That would mean it is a bug in GCC 10.4 also :(.
> 
> It's not, even though 10.4 has the library change. Compiling the test case
> with 10.4 works. But preprocessing with 10.4 and then compiling with 11.1
> fails, confirming a front end change is to blame.
> 
> Bisection shows it started to error with r11-2774
Revisiting this bug while analyzing PR112490, I noticed it's interesting that
the testcase started failing after CWG 2369 even though none of the involved
functions have non-dependent parameters (and so there are no non-dependent
conversions).

Ah, that's because another consequence of CWG 2369 is that the validity of a
function's substituted return type is now checked after constraints instead of
beforehand, which turns out to make a difference here.

So FWIW another workaround to restore the pre-CWG 2369 semantics would be to
check the return type of the problematic std::optional<=> earlier:

diff --git a/libstdc++-v3/include/std/optional
b/libstdc++-v3/include/std/optional
index 832dc6fd84b..a616dc07b10 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -1685,7 +1685,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION

   template<typename _Tp, typename _Up>
     requires (!__is_derived_from_optional<_Up>)
-      && three_way_comparable_with<_Up, _Tp>
+      && requires { typename compare_three_way_result_t<_Tp, _Up>; }
+      && three_way_comparable_with<_Tp, _Up>
     constexpr compare_three_way_result_t<_Tp, _Up>
     operator<=> [[nodiscard]] (const optional<_Tp>& __x, const _Up& __v)
     { return bool(__x) ? *__x <=> __v : strong_ordering::less; }

Reply via email to