public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637
@ 2021-09-18  8:02 dangelog at gmail dot com
  2021-09-27 12:51 ` [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get, at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02 marxin at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: dangelog at gmail dot com @ 2021-09-18  8:02 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 102396
           Summary: ICE when using concepts, in get, at
                    cp/constraint.cc:2637
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dangelog at gmail dot com
  Target Milestone: ---

Hello,

This testcase (which gets accepted by Clang and MSVC) causes an ICE under
GCC-12-trunk, and an erroneous compilation error on GCC 11.2.


#include <memory>
#include <span>
#include <ranges>
#include <concepts>

template <typename T> struct S;

template <typename C> constexpr bool is_S = false;
template <typename T> constexpr bool is_S<S<T>> = true;

template <typename T>
struct S {
    T data;

    S();
    explicit S(const T &);

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

template <typename T>
bool operator==(const S<T> &a, const S<T> &b) { return a.data == b.data; }


int main() {
    using SD = S<double>;

    char data[sizeof(SD) * 10];
    std::span<SD> span((SD*)std::begin(data), (SD*)std::end(data));

    //static_assert(std::equality_comparable<std::span<SD>::iterator>);

    std::ranges::uninitialized_default_construct(span);
}



The error:



/opt/compiler-explorer/gcc-trunk-20210918/include/c++/12.0.0/concepts:280:17:
internal compiler error: in get, at cp/constraint.cc:2637
  280 |           { __t == __u } -> __boolean_testable;
      |             ~~~~^~~~~~
0x1fc77b9 internal_error(char const*, ...)
        ???:0
0x713d19 fancy_abort(char const*, int, char const*)
        ???:0
0x7970af satisfaction_cache::get()
        ???:0
0x79cd8a constraints_satisfied_p(tree_node*, tree_node*)
        ???:0
0x9ba323 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node*
const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool,
bool)
        ???:0
0x73f150 build_new_op(op_location_t const&, tree_code, int, tree_node*,
tree_node*, tree_node*, tree_node**, int)
        ???:0
0xa2fc50 build_x_binary_op(op_location_t const&, tree_code, tree_node*,
tree_code, tree_node*, tree_code, tree_node**, int)
        ???:0
0x79cd42 tsubst_requires_expr(tree_node*, tree_node*, int, tree_node*)
        ???:0
0x79cd8a constraints_satisfied_p(tree_node*, tree_node*)
        ???:0
0x9ba323 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node*
const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool,
bool)
        ???:0
0x73f150 build_new_op(op_location_t const&, tree_code, int, tree_node*,
tree_node*, tree_node*, tree_node**, int)
        ???:0
0xa2fc50 build_x_binary_op(op_location_t const&, tree_code, tree_node*,
tree_code, tree_node*, tree_code, tree_node**, int)
        ???:0
0x9816d7 instantiate_decl(tree_node*, bool, bool)
        ???:0
0x9c3e1b instantiate_pending_templates(int)
        ???:0
0x82a899 c_parse_final_cleanups()
        ???:0

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get,  at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02
  2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
@ 2021-09-27 12:51 ` marxin at gcc dot gnu.org
  2021-11-05 13:23 ` rguenth at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: marxin at gcc dot gnu.org @ 2021-09-27 12:51 UTC (permalink / raw)
  To: gcc-bugs

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

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |marxin at gcc dot gnu.org,
                   |                            |ppalka at gcc dot gnu.org
            Summary|ICE when using concepts, in |[11/12 Regression] ICE when
                   |get, at                     |using concepts, in get, at
                   |cp/constraint.cc:2637       |cp/constraint.cc:2637 since
                   |                            |r11-6245-g79f57d5cb070bb02
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2021-09-27

--- Comment #1 from Martin Liška <marxin at gcc dot gnu.org> ---
Likely started with r11-6245-g79f57d5cb070bb02.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get,  at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02
  2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
  2021-09-27 12:51 ` [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get, at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02 marxin at gcc dot gnu.org
@ 2021-11-05 13:23 ` rguenth at gcc dot gnu.org
  2021-11-05 14:01 ` ppalka at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2021-11-05 13:23 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2
   Target Milestone|---                         |11.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get,  at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02
  2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
  2021-09-27 12:51 ` [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get, at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02 marxin at gcc dot gnu.org
  2021-11-05 13:23 ` rguenth at gcc dot gnu.org
@ 2021-11-05 14:01 ` ppalka at gcc dot gnu.org
  2021-12-09 18:52 ` dangelog at gmail dot com
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: ppalka at gcc dot gnu.org @ 2021-11-05 14:01 UTC (permalink / raw)
  To: gcc-bugs

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 ***

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get,  at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02
  2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
                   ` (2 preceding siblings ...)
  2021-11-05 14:01 ` ppalka at gcc dot gnu.org
@ 2021-12-09 18:52 ` dangelog at gmail dot com
  2021-12-09 18:54 ` dangelog at gmail dot com
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: dangelog at gmail dot com @ 2021-12-09 18:52 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Giuseppe D'Angelo <dangelog at gmail dot com> ---
Hello Patrick,

Thank you for the insights. I'm left wondering however if the CWG resolution
would possibly ever allow the operator== to be defined as a hidden friend; the
workaround you mentioned may lead to redefinition errors (as now it doesn't
depend on S any more)?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get,  at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02
  2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
                   ` (3 preceding siblings ...)
  2021-12-09 18:52 ` dangelog at gmail dot com
@ 2021-12-09 18:54 ` dangelog at gmail dot com
  2021-12-11 16:13 ` ppalka at gcc dot gnu.org
  2021-12-13 16:58 ` dangelog at gmail dot com
  6 siblings, 0 replies; 8+ messages in thread
From: dangelog at gmail dot com @ 2021-12-09 18:54 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Giuseppe D'Angelo <dangelog at gmail dot com> ---
To elaborate on the last comment, this testcase does complain about the
redefinition. 


    #include <type_traits>
    #include <concepts>


    template <typename T> class S;

    template <typename T>
    static inline std::true_type is_S_impl(const S<T>&);
    static inline std::false_type is_S_impl(...);

    template <typename T>
    concept is_S = decltype(is_S_impl(std::declval<T>()))::value;



    template <typename T>
    struct S {
        using type = T;
        T data;

        S();
        explicit S(const T &);

        template <typename V, typename U>
        requires is_S<V> && (!is_S<U>) &&
std::equality_comparable_with<typename V::type, U>
        friend bool operator==(const V &v, const U &u) { return v.data == u; }
    };

    void f() {
        S<int> s1; s1 == 123;
        S<double> s2; s2 == 123.4;
    }

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get,  at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02
  2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
                   ` (4 preceding siblings ...)
  2021-12-09 18:54 ` dangelog at gmail dot com
@ 2021-12-11 16:13 ` ppalka at gcc dot gnu.org
  2021-12-13 16:58 ` dangelog at gmail dot com
  6 siblings, 0 replies; 8+ messages in thread
From: ppalka at gcc dot gnu.org @ 2021-12-11 16:13 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Giuseppe D'Angelo from comment #3)
> Hello Patrick,
> 
> Thank you for the insights. I'm left wondering however if the CWG resolution
> would possibly ever allow the operator== to be defined as a hidden friend;
> the workaround you mentioned may lead to redefinition errors (as now it
> doesn't depend on S any more)?

Ah yeah, I ran into a similar issue when implementing the pipe operator for
range adaptor closures in libstdc++... IIRC, I worked around this by
introducing a non-template base class and defining the hidden template friend
in the base class instead.  So something like:

#include <type_traits>
#include <concepts>


template <typename T> class S;

template <typename T>
static inline std::true_type is_S_impl(const S<T>&);
static inline std::false_type is_S_impl(...);

template <typename T>
concept is_S = decltype(is_S_impl(std::declval<T>()))::value;


template <typename T>
struct S;

struct S_Base {
    template <typename V, typename U>
    requires is_S<V> && (!is_S<U>) && std::equality_comparable_with<typename
V::type, U>
    friend bool operator==(const V &v, const U &u) { return v.data == u; }
};

template <typename T>
struct S : private S_Base {
    using type = T;
    T data;

    S();
    explicit S(const T &);
};

void f() {
    S<int> s1; s1 == 123;
    S<double> s2; s2 == 123.4;
}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get,  at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02
  2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
                   ` (5 preceding siblings ...)
  2021-12-11 16:13 ` ppalka at gcc dot gnu.org
@ 2021-12-13 16:58 ` dangelog at gmail dot com
  6 siblings, 0 replies; 8+ messages in thread
From: dangelog at gmail dot com @ 2021-12-13 16:58 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Giuseppe D'Angelo <dangelog at gmail dot com> ---
That's brilliant! I really hadn't thought that pushing the hidden friend into a
private base would work nonetheless. Thanks!

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-12-13 16:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-18  8:02 [Bug c++/102396] New: ICE when using concepts, in get, at cp/constraint.cc:2637 dangelog at gmail dot com
2021-09-27 12:51 ` [Bug c++/102396] [11/12 Regression] ICE when using concepts, in get, at cp/constraint.cc:2637 since r11-6245-g79f57d5cb070bb02 marxin at gcc dot gnu.org
2021-11-05 13:23 ` rguenth at gcc dot gnu.org
2021-11-05 14:01 ` ppalka at gcc dot gnu.org
2021-12-09 18:52 ` dangelog at gmail dot com
2021-12-09 18:54 ` dangelog at gmail dot com
2021-12-11 16:13 ` ppalka at gcc dot gnu.org
2021-12-13 16:58 ` dangelog at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).