Summary: | ICE with spaceship in constexpr evaluation | ||
---|---|---|---|
Product: | gcc | Reporter: | Jonathan Wakely <redi> |
Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | NEW --- | ||
Severity: | normal | CC: | jakub, jason, webrown.cpp |
Priority: | P3 | Keywords: | ice-on-valid-code |
Version: | 10.0 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2019-11-09 00:00:00 | |
Bug Depends on: | |||
Bug Blocks: | 55004 |
Description
Jonathan Wakely
2019-11-09 11:19:53 UTC
Reduced: #include <compare> template<typename T, typename U> constexpr std::weak_ordering cmp(T e, U f) { return e <=> f; } auto o = cmp(1, 2); wo.cc:10:18: in 'constexpr' expansion of 'cmp<int, int>(1, 2)' wo.cc:10:18: internal compiler error: in cxx_eval_constant_expression, at cp/constexpr.c:5123 10 | auto o = cmp(1, 2); | ^ Related to converting the strong_ordering result of <=> to weak_ordering? Slightly further reduced: #include <compare> constexpr std::weak_ordering cmp(int e, int f) { return e <=> f; } auto o = cmp(1, 2); Further reduced: namespace std { enum E { e }; struct strong_ordering { int c; constexpr strong_ordering(E) : c () {} static const strong_ordering less; static strong_ordering equal; static strong_ordering greater; constexpr operator int() {} }; strong_ordering constexpr strong_ordering::less(e); } constexpr int cmp (int d, int e) { return d <=> e; } auto f = cmp (1, 2); We have ADDR_EXPR of a SPACESHIP_EXPR originally, the SPACESHIP_EXPR is constexpr evaluated into a CONSTRUCTOR but the ADDR_EXPR handling code in in cxx_eval_constant_expression asserts that ADDR_EXPR operand doesn't evaluate into a CONSTRUCTOR when lval is true. Author: redi Date: Wed Nov 13 16:26:18 2019 New Revision: 278149 URL: https://gcc.gnu.org/viewcvs?rev=278149&root=gcc&view=rev Log: libsupc++: Implement comparison algorithms for C++20 This is incomplete because std::strong_order doesn't support floating-point types. The partial_order and weak_order tests use VERIFY instead of static_assert because of PR 92431. * libsupc++/compare (strong_order, weak_order, partial_order) (compare_strong_order_fallback, compare_weak_order_fallback) (compare_partial_order_fallback): Define customization point objects for C++20. * testsuite/18_support/comparisons/algorithms/partial_order.cc: New test. * testsuite/18_support/comparisons/algorithms/strong_order.cc: New test. * testsuite/18_support/comparisons/algorithms/weak_order.cc: New test. Added: trunk/libstdc++-v3/testsuite/18_support/comparisons/algorithms/ trunk/libstdc++-v3/testsuite/18_support/comparisons/algorithms/partial_order.cc trunk/libstdc++-v3/testsuite/18_support/comparisons/algorithms/strong_order.cc trunk/libstdc++-v3/testsuite/18_support/comparisons/algorithms/weak_order.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/libsupc++/compare This was fixed by r10-6572-dfffecb802681fbdb56629d3bdd96491ac660be0 c++: Fix static initialization from <=>. Constant evaluation of genericize_spaceship produced a CONSTRUCTOR, which we then wanted to bind to a reference, which we can't do. So wrap the result in a TARGET_EXPR so we get something with an address. We also need to handle treating the result of cxx_eval_binary_expression as a glvalue for SPACESHIP_EXPR. My earlier change to add uid_sensitive to maybe_constant_value was wrong; we don't even look at the cache when manifestly_const_eval, and I failed to adjust the later call to cxx_eval_outermost_constant_expr. gcc/cp/ChangeLog 2020-02-11 Jason Merrill <jason@redhat.com> PR c++/93650 PR c++/90691 * constexpr.c (maybe_constant_value): Correct earlier change. (cxx_eval_binary_expression) [SPACESHIP_EXPR]: Pass lval through. * method.c (genericize_spaceship): Wrap result in TARGET_EXPR. (In reply to Jonathan Wakely from comment #4) > This is incomplete because std::strong_order doesn't support > floating-point types. See PR 96526 regarding that. > The partial_order and weak_order tests use VERIFY instead of > static_assert because of PR 92431. Some of those VERIFYs have been changed to static_assert in r11-2609 Looks to be fixed for the GCC 10 release. |