https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100291
Bug ID: 100291 Summary: internal compiler error: trying to capture ‘this’ in instantiation of generic lambda Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: mpolacek at gcc dot gnu.org Target Milestone: --- template <typename _Tp, _Tp __v> struct integral_constant { static constexpr _Tp value = __v; }; template <bool __v> using bool_constant = integral_constant<bool, __v>; template <typename> struct conditional; template <typename...> struct __and_; template <typename _B1, typename _B2> struct __and_<_B1, _B2> : conditional<_B2>::type {}; template <typename _Tp, typename _Up = _Tp> _Up __declval(int); template <typename _Tp> auto declval() -> decltype(__declval<_Tp>(0)); template <typename _Iftrue> struct conditional { typedef _Iftrue type; }; template <typename> using void_t = void; template <typename> struct iterator_traits; template <typename _Tp> struct iterator_traits<_Tp *> { typedef _Tp reference; }; struct pointer_traits { template <typename _Up> using rebind = _Up *; }; template <typename _Iterator> class __normal_iterator { public: typename iterator_traits<_Iterator>::reference operator*(); }; template <typename _Tp> class allocator { public: typedef _Tp value_type; }; template <typename _Alloc> struct allocator_traits { template <typename _Tp> struct _Ptr { using type = pointer_traits::rebind<_Tp>; }; using const_pointer = typename _Ptr<typename _Alloc::value_type>::type; }; template <typename _Alloc> struct _Vector_base { typedef allocator_traits<_Alloc> _Tp_alloc_type; }; template <typename _Tp, typename _Alloc = allocator<_Tp>> class vector { typedef typename _Vector_base<_Alloc>::_Tp_alloc_type _Alloc_traits; public: __normal_iterator<typename _Alloc_traits::const_pointer> begin() const; }; template <class, class, template <class> class, class...> struct detector; template <class Default, template <class> class Op, class... Args> struct detector<Default, void_t<Op<Args...>>, Op, Args...> { using value_t = integral_constant<bool, true>; }; template <template <class> class Op, class... Args> using is_detected = typename detector<int, void, Op, Args...>::value_t; template <bool... Bs> constexpr bool require = __and_<bool_constant<Bs>...>::value; template <typename T, typename R, template <class...> class M, typename... Arguments> constexpr bool has_method = M<T, R, Arguments...>::template tv<T>::value; template <class T, typename, typename... Arguments> struct time_t { template <typename T_> struct fptr_meta { template <typename... Arguments_> using type = integral_constant<decltype(T_().time(declval<Arguments_>()...)) (T_::*)( Arguments_...) const, &T_::time>; }; template <typename T_, typename... Arguments_> using fptr_meta_t = typename fptr_meta<T_>::template type<Arguments_...>; template <typename> struct tv { static constexpr bool value = is_detected<fptr_meta_t, T, Arguments...>::value; }; }; template <class T, typename, typename... Arguments> struct output_step_size_t { template <typename T_> struct fptr_meta { template <typename... Arguments_> using type = integral_constant<decltype(T_().outputStepSize( declval<Arguments_>()...)) (T_::*)(Arguments_...) const, &T_::outputStepSize>; }; template <typename T_, typename... Arguments_> using fptr_meta_t = typename fptr_meta<T_>::template type<Arguments_...>; template <typename> struct tv { static constexpr bool value = is_detected<fptr_meta_t, T, Arguments...>::value; }; }; template <typename S, typename state = typename S::State> struct Trans_NS_Stepper_StepperConcept { constexpr static bool time_exists = has_method<S, double, time_t, const state &>; constexpr static bool output_step_size_exists = has_method<S, char, output_step_size_t, const state &>; constexpr static bool value = require<time_exists, output_step_size_exists>; }; template <typename stepper> constexpr bool StepperConcept = Trans_NS_Stepper_StepperConcept<stepper>::value; template <typename stepper_t> class Propagator { static_assert(StepperConcept<stepper_t>); }; template <typename = int> class EigenStepper { public: struct State {}; void time(State); }; template <typename _InputIterator, typename _Tp, typename _BinaryOperation> void accumulate(_InputIterator __first, _Tp __init, _BinaryOperation __binary_op) { __binary_op(__init, *__first); } template <typename extensionlist_t = int> class MultiEigenStepper : EigenStepper<> { public: using SingleStepper = EigenStepper<extensionlist_t>; using SingleState = State; struct State { struct Component { SingleState state; }; vector<Component> components; }; void time(const State &state) const { accumulate(state.components.begin(), 0.0, [&](auto, auto cmp) { SingleStepper::time(cmp.state); }); } void outputStepSize(const State &) const; }; using MultiStepper = MultiEigenStepper<>; using MultiPropagator = Propagator<MultiStepper>; MultiPropagator makePropagator() { return {}; } gives $ ./cc1plus -quiet w.C w.C: In instantiation of ‘MultiEigenStepper<>::time(const MultiEigenStepper<>::State&) const::<lambda(auto:1, auto:2)> [with auto:1 = double; auto:2 = MultiEigenStepper<>::State::Component]’: w.C:104:14: required from ‘void accumulate(_InputIterator, _Tp, _BinaryOperation) [with _InputIterator = __normal_iterator<MultiEigenStepper<>::State::Component*>; _Tp = double; _BinaryOperation = MultiEigenStepper<>::time(const MultiEigenStepper<>::State&) const::<lambda(auto:1, auto:2)>]’ w.C:118:15: required from ‘void MultiEigenStepper<extensionlist_t>::time(const MultiEigenStepper<extensionlist_t>::State&) const [with extensionlist_t = int]’ w.C:60:27: required by substitution of ‘template<class T, class, class ... Arguments> template<class T_> template<class ... Arguments_> using type = integral_constant<decltype (T_().time((declval<Arguments_>)()...)) (T_::*)(Arguments_ ...) const, (& T_::time)> [with Arguments_ = {const MultiEigenStepper<>::State&}; T_ = MultiEigenStepper<>; T = MultiEigenStepper<>; <template-parameter-1-2> = double; Arguments = {const MultiEigenStepper<>::State&}]’ w.C:63:9: required by substitution of ‘template<class T, class, class ... Arguments> template<class T_, class ... Arguments_> using fptr_meta_t = typename time_t<T, <template-parameter-1-2>, Arguments>::fptr_meta::type<Arguments_ ...> [with T_ = MultiEigenStepper<>; Arguments_ = {const MultiEigenStepper<>::State&}; T = MultiEigenStepper<>; <template-parameter-1-2> = double; Arguments = {const MultiEigenStepper<>::State&}]’ w.C:48:7: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] w.C:65:78: required from ‘constexpr const bool time_t<MultiEigenStepper<>, double, const MultiEigenStepper<>::State&>::tv<MultiEigenStepper<> >::value’ w.C:53:68: required from ‘constexpr const bool has_method<MultiEigenStepper<>, double, template<class T, class, class ... Arguments> struct time_t, const MultiEigenStepper<>::State&>’ w.C:86:7: required from ‘constexpr const bool Trans_NS_Stepper_StepperConcept<MultiEigenStepper<>, MultiEigenStepper<>::State>::time_exists’ w.C:89:33: required from ‘constexpr const bool Trans_NS_Stepper_StepperConcept<MultiEigenStepper<>, MultiEigenStepper<>::State>::value’ w.C:92:75: required from ‘constexpr const bool StepperConcept<MultiEigenStepper<> >’ w.C:94:17: required from ‘class Propagator<MultiEigenStepper<> >’ w.C:125:32: required from here w.C:119:38: internal compiler error: trying to capture ‘this’ in instantiation of generic lambda 119 | [&](auto, auto cmp) { SingleStepper::time(cmp.state); }); | ^~~~~~~~~~~~~ 0xbb7b2b add_capture(tree_node*, tree_node*, tree_node*, bool, bool) /home/mpolacek/src/gcc/gcc/cp/lambda.c:637 0xbb7f4e add_default_capture(tree_node*, tree_node*, tree_node*) /home/mpolacek/src/gcc/gcc/cp/lambda.c:697 0xbb8df2 lambda_expr_this_capture(tree_node*, int) /home/mpolacek/src/gcc/gcc/cp/lambda.c:815 0xbb9795 maybe_resolve_dummy(tree_node*, bool) /home/mpolacek/src/gcc/gcc/cp/lambda.c:898 0xa47d12 build_new_method_call_1 /home/mpolacek/src/gcc/gcc/cp/call.c:10756 0xa4829c build_new_method_call(tree_node*, tree_node*, vec<tree_node*, va_gc, vl_embed>**, tree_node*, int, tree_node**, int) /home/mpolacek/src/gcc/gcc/cp/call.c:10859 0xd4d52e tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool) /home/mpolacek/src/gcc/gcc/cp/pt.c:20509 0xd474cd tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/mpolacek/src/gcc/gcc/cp/pt.c:19204 0xd3fbf5 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/mpolacek/src/gcc/gcc/cp/pt.c:18274 0xd4282c tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/mpolacek/src/gcc/gcc/cp/pt.c:18595 0xd4282c tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/mpolacek/src/gcc/gcc/cp/pt.c:18595 0xd64c3c instantiate_body /home/mpolacek/src/gcc/gcc/cp/pt.c:25921 0xd6662c instantiate_decl(tree_node*, bool, bool) /home/mpolacek/src/gcc/gcc/cp/pt.c:26215 0xb7a288 maybe_instantiate_decl(tree_node*) /home/mpolacek/src/gcc/gcc/cp/decl2.c:5460 0xb7c828 mark_used(tree_node*, int) /home/mpolacek/src/gcc/gcc/cp/decl2.c:5689 0xa42dc6 build_over_call /home/mpolacek/src/gcc/gcc/cp/call.c:9493 0xa315b5 build_op_call_1 /home/mpolacek/src/gcc/gcc/cp/call.c:4967 0xa3174b build_op_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, int) /home/mpolacek/src/gcc/gcc/cp/call.c:4996 0xd97d4d finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) /home/mpolacek/src/gcc/gcc/cp/semantics.c:2851 0xd4d656 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool) /home/mpolacek/src/gcc/gcc/cp/pt.c:20530