https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115561
Bug ID: 115561
Summary: [14/15 Regression] ICE checking constraints when a
local class is involved
Product: gcc
Version: 14.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: rs2740 at gmail dot com
Target Milestone: ---
Reduced test case:
template<typename _Tp>
auto declval() noexcept -> _Tp&&;
template<bool, typename _Tp = void>
struct enable_if
{ };
template<typename _Tp>
struct enable_if<true, _Tp>
{ using type = _Tp; };
template<bool _Cond, typename _Tp = void>
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
template<typename _Tp>
struct is_void
{ static constexpr bool value = false; };
template<typename Fun, typename... Args>
using invoke_result_t =
decltype(declval<Fun>()(declval<Args>()...));
template<typename R>
using iter_reference_t = decltype(*declval<R &>());
struct iter_move_fn
{
template<typename I>
constexpr
auto operator() (I &&i) -> void;
} iter_move;
template<typename I>
using iter_rvalue_reference_t = decltype(iter_move(declval<I &>()));
template<class, class>
concept same_as = true;
template<typename I>
concept readable_concept_ =
same_as<iter_rvalue_reference_t<I const>, iter_rvalue_reference_t<I>>;
template<typename I>
concept indirectly_readable =
readable_concept_<enable_if_t<true, I>>;
template<typename Fun, typename I>
using indirect_result_t =
enable_if_t<indirectly_readable<I>,
invoke_result_t<Fun, iter_reference_t<I>>>;
template<typename I, typename Fun>
concept transformable =
(!is_void<indirect_result_t<Fun &, I>>::value);
template<typename I, typename Fun >
requires transformable<I, Fun>
constexpr void transform(I, Fun)
{
}
void foo()
{
struct B {};
(void) transform((B*)nullptr, [](B) {return 0; });
}
With GCC 14.1, g++ -std=c++20 crashes:
test2.cpp: In substitution of ‘template<class I, class Fun> requires
transformable<I, Fun> constexpr void transform(I, Fun) [with I = foo()::B*; Fun
= foo()::<lambda(foo()::B)>]’:
test2.cpp:65:21: required from here
65 | (void) transform((B*)nullptr, [](B) {return 0; });
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test2.cpp:34:51: internal compiler error: Segmentation fault
34 | using iter_rvalue_reference_t = decltype(iter_move(declval<I &>()));
| ~~~~~~~~~^~~~~~~~~~~~~~~~
0xe9ea2f crash_signal
../../gcc/toplev.cc:319
0x8fc014 finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool,
bool, int)
../../gcc/cp/semantics.cc:2971
0x8c9cd7 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
../../gcc/cp/pt.cc:21081
0x8ce166 tsubst(tree_node*, tree_node*, int, tree_node*)
../../gcc/cp/pt.cc:16929
0x8cf7a4 tsubst_template_args(tree_node*, tree_node*, int, tree_node*)
../../gcc/cp/pt.cc:13923
0x77dfbf normalize_concept_check
../../gcc/cp/constraint.cc:761
0x77dfbf normalize_atom
../../gcc/cp/constraint.cc:816
0x77dfbf normalize_expression
../../gcc/cp/constraint.cc:886
0x77e5f1 normalize_concept_check
../../gcc/cp/constraint.cc:795
0x77e5f1 normalize_atom
../../gcc/cp/constraint.cc:816
0x77e5f1 normalize_expression
../../gcc/cp/constraint.cc:886
0x780070 get_normalized_constraints
../../gcc/cp/constraint.cc:898
0x780070 normalize_concept_definition
../../gcc/cp/constraint.cc:1016
0x780070 satisfy_nondeclaration_constraints
../../gcc/cp/constraint.cc:3225
0x780070 constraint_satisfaction_value
../../gcc/cp/constraint.cc:3411
0x78275e evaluate_concept_check(tree_node*)
../../gcc/cp/constraint.cc:3459
0x76d7e3 cxx_eval_constant_expression
../../gcc/cp/constexpr.cc:8519
0x7740b7 cxx_eval_outermost_constant_expr
../../gcc/cp/constexpr.cc:8857
0x777bd5 maybe_constant_value(tree_node*, tree_node*, mce_value)
../../gcc/cp/constexpr.cc:9145
0x8cada4 convert_nontype_argument
../../gcc/cp/pt.cc:7521
Also crashes on godbolt GCC trunk. GCC 13.2 compiles this OK. Moving the
definition of struct B to global scope makes the crash go away.