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; }