https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102396
Patrick Palka <ppalka at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords|ice-on-valid-code |ice-on-invalid-code
Resolution|--- |DUPLICATE
Status|NEW |RESOLVED
--- Comment #2 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Martin Liška from comment #1)
> Likely started with r11-6245-g79f57d5cb070bb02.
Looks like we went from accepting to rejecting this testcase with r11-2774, and
then with r11-6245 we went from rejecting to ICEing (due to a failing
gcc_checking_assert). In order to fix the ICE, I think we should just remove
the problematic assert.
However, note that the testcase is strictly speaking invalid ever since the
resolution of CWG2369 which changes the point at which we check constraints
during template argument deduction. We now check constraints sooner, in
particular _before_ checking non-dependent conversions, and this change can
sometimes unexpectedly lead to constraint recursion, see PR100288 and the
related PRs for more detail. I believe Clang and MSVC accept this testcase
because they don't implement CWG2369.
The workaround is to encode the non-dependent conversion for first parameter of
the recursive constrained operator== into its own constraint:
diff --git a/102396.C b/102396.C
index dbf2258..3fd2816 100644
--- a/102396.C
+++ b/102396.C
@@ -15,10 +15,10 @@ struct S {
S();
explicit S(const T &);
- template <typename U,
+ template <typename V, typename U,
std::enable_if_t<!is_S<U>, bool> = false>
- requires std::equality_comparable_with<T, U>
- friend bool operator==(const S &s, const U &u) { return s.data == u; }
+ requires is_S<V> && std::equality_comparable_with<T, U>
+ friend bool operator==(const V &s, const U &u) { return s.data == u; }
};
template <typename T>
*** This bug has been marked as a duplicate of bug 100288 ***