Bug 92431 - ICE with spaceship in constexpr evaluation
Summary: ICE with spaceship in constexpr evaluation
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2019-11-09 11:19 UTC by Jonathan Wakely
Modified: 2019-11-15 13:16 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-11-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2019-11-09 11:19:53 UTC
This crashes when compiled with -std=gnu++2a:


#include <compare>

template<typename _Tp, typename _Up>
  concept op_cmp = requires(_Tp&& __t, _Up&& __u)
  {
    std::weak_ordering(static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u));
  };

struct Weak_order
{
  template<typename _Tp, typename _Up>
    constexpr std::weak_ordering
    operator()(_Tp&& __e, _Up&& __f) const
    {
      if constexpr (op_cmp<_Tp, _Up>)
        return static_cast<_Tp&&>(__e) <=> static_cast<_Up&&>(__f);
    }
};

constexpr Weak_order weak_order{};

auto o = weak_order(1, 2);




wo.cc:22:25:   in 'constexpr' expansion of 'weak_order.Weak_order::operator()<int, int>(1, 2)'
wo.cc:22:25: internal compiler error: in cxx_eval_constant_expression, at cp/constexpr.c:5123
   22 | auto o = weak_order(1, 2);
      |                         ^
0x5d0fd7 cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:5123
0x88f898 cxx_bind_parameters_in_call
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:1424
0x88f898 cxx_eval_call_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:1921
0x892d5a cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:4924
0x893cbd cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:4995
0x89c27a cxx_eval_store_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:4254
0x893046 cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:5013
0x8916d3 cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:5025
0x892513 cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:5064
0x893da0 cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:5327
0x890adb cxx_eval_call_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:2072
0x892d5a cxx_eval_constant_expression
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:4924
0x895d8e cxx_eval_outermost_constant_expr
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:5868
0x89a24b maybe_constant_value(tree_node*, tree_node*, bool)
        /home/jwakely/src/gcc/gcc/gcc/cp/constexpr.c:6138
0xa55490 store_init_value(tree_node*, tree_node*, vec<tree_node*, va_gc, vl_embed>**, int)
        /home/jwakely/src/gcc/gcc/gcc/cp/typeck2.c:858
0x8c952d check_initializer
        /home/jwakely/src/gcc/gcc/gcc/cp/decl.c:6718
0x8ebfdf cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int)
        /home/jwakely/src/gcc/gcc/gcc/cp/decl.c:7634
0x99660e cp_parser_init_declarator
        /home/jwakely/src/gcc/gcc/gcc/cp/parser.c:20727
0x9764b2 cp_parser_simple_declaration
        /home/jwakely/src/gcc/gcc/gcc/cp/parser.c:13624
0x99e997 cp_parser_declaration
        /home/jwakely/src/gcc/gcc/gcc/cp/parser.c:13322
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Comment 1 Jonathan Wakely 2019-11-09 16:30: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?
Comment 2 Jonathan Wakely 2019-11-09 16:31:57 UTC
Slightly further reduced:

#include <compare>

constexpr std::weak_ordering
cmp(int e, int f)
{
  return e <=> f;
}

auto o = cmp(1, 2);
Comment 3 Jakub Jelinek 2019-11-09 18:17:58 UTC
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.
Comment 4 Jonathan Wakely 2019-11-13 16:26:50 UTC
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