Created attachment 51695 [details] Source code that causes the ICE Hello, g++-11.1 (Arch Linux). Here's the stack trace I'm getting: $ g++ -fPIC -fcoroutines -std=gnu++20 -c out.cpp In file included from /usr/include/boost/pfr/detail/core17.hpp:11, from /usr/include/boost/pfr/detail/core.hpp:17, from /usr/include/boost/pfr/core.hpp:12, from /usr/include/boost/pfr.hpp:12, from /home/jcelerier/projets/perso/avendish/src/avnd/concepts/generic.hpp:6, from /home/jcelerier/projets/perso/avendish/src/avnd/concepts/audio_port.hpp:6, from /home/jcelerier/projets/perso/avendish/src/avnd/concepts.hpp:6, from /home/jcelerier/projets/perso/avendish/src/avnd/prepare.hpp:5, from /home/jcelerier/projets/perso/avendish/src/avnd/avnd.hpp:5, from /home/jcelerier/projets/perso/avendish/src/python/processor.hpp:5, from /tmp/sdfljifg/examples__Helpers_python.cpp:5: /usr/include/boost/pfr/detail/fields_count.hpp: In substitution of ‘template<class T, long unsigned int N> constexpr decltype (sizeof (T{})) boost::pfr::detail::detect_fields_count_dispatch(boost::pfr::detail::size_t_<I>, long int, int) [with T = examples::Helpers<python::config>::<unnamed struct>; long unsigned int N = <missing>]’: /usr/include/boost/pfr/detail/fields_count.hpp:243:78: required from ‘constexpr std::size_t boost::pfr::detail::fields_count() [with T = const examples::Helpers<python::config>::<unnamed struct>; std::size_t = long unsigned int]’ /usr/include/boost/pfr/detail/core17.hpp:54:54: required from ‘constexpr auto boost::pfr::detail::tie_as_tuple(T&) [with T = const examples::Helpers<python::config>::<unnamed struct>]’ /usr/include/boost/pfr/core.hpp:106:29: required from ‘constexpr auto boost::pfr::structure_to_tuple(const T&) [with T = examples::Helpers<python::config>::<unnamed struct>]’ /home/jcelerier/projets/perso/avendish/src/avnd/concepts/port.hpp:12:424: required from ‘struct avnd::inputs_type<examples::Helpers<python::config> >’ /home/jcelerier/projets/perso/avendish/src/avnd/input_introspection.hpp:13:7: required by substitution of ‘template<class T> using parameter_input_introspection = avnd::parameter_introspection<typename avnd::inputs_type<T>::type> [with T = examples::Helpers<python::config>]’ /home/jcelerier/projets/perso/avendish/src/python/processor.hpp:47:54: required from ‘python::processor<T>::processor(pybind11::module_&) [with T = examples::Helpers<python::config>]’ /tmp/sdfljifg/examples__Helpers_python.cpp:10:52: required from here /usr/include/boost/pfr/detail/fields_count.hpp:189:17: internal compiler error: in tsubst_copy_and_build, at cp/pt.c:19856 189 | -> decltype(sizeof(T{})) | ^~~~~~~~~~~ 0x1797368 internal_error(char const*, ...) ???:0 0x67f8f9 fancy_abort(char const*, int, char const*) ???:0 0x6be30e fold_non_dependent_init(tree_node*, int, bool, tree_node*) ???:0 0x816127 finish_compound_literal(tree_node*, tree_node*, int, fcl_t) ???:0 0x7e78a9 tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0x7e721e tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0x803139 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node* const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool, bool) ???:0 0x6994f5 build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, int) ???:0 0x8177bc finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) ???:0 0x7ea4ef instantiate_decl(tree_node*, bool, bool) ???:0 0xfa14b3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*)) ???:0 0xfa16a0 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*)) ???:0 0xfa37da walk_tree_without_duplicates_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*)) ???:0 0x6bdef4 maybe_constant_value(tree_node*, tree_node*, bool) ???:0 0x7e7c3a tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0x7ea4ef instantiate_decl(tree_node*, bool, bool) ???:0 0x711996 mark_used(tree_node*, int) ???:0 0x69950a build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, int) ???:0 0x8177bc finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) ???:0 0x7ea4ef instantiate_decl(tree_node*, bool, bool) ???:0
Reducing.
Still reducing it, down to 2.2M file
Reduced testcase: template <int a> struct f{}; template<double setup> struct knob_t { int value = setup; }; struct Helpers { knob_t<1.0> inputs; }; template <class T, int N> auto h(f<N> a) noexcept -> decltype(sizeof(T{})); int t = h<Helpers>(f<1>{});
*** Bug 103019 has been marked as a duplicate of this bug. ***
Note you can also invoke this on invalid code too: template<double setup> struct knob_t { int value = setup; }; struct Helpers { knob_t<1.0> inputs; }; template <class T, int N> auto h() noexcept -> decltype(sizeof(T{})); int t = h<Helpers>();
Reduced C++11 ICE-on-valid testcase: struct knob_t { int value = 1.0; }; struct Helpers { knob_t inputs; }; template<class> void f(decltype(Helpers{})); ICEs with -std=c++14 since r9-5678 (but -std=c++11 is ok)
Oof, mine then. Thanks for reducing this.
*** Bug 104720 has been marked as a duplicate of this bug. ***
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:f0530882d99abc410bb080051aa04e5cea848f18 commit r12-7803-gf0530882d99abc410bb080051aa04e5cea848f18 Author: Marek Polacek <polacek@redhat.com> Date: Tue Mar 22 18:42:27 2022 -0400 c++: FIX_TRUNC_EXPR in tsubst [PR102990] This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build where it hits gcc_unreachable (). The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it was introduced in r181478, but it did the wrong thing, whereupon it was turned into gcc_unreachable () in r258821 (see this thread: <https://gcc.gnu.org/pipermail/gcc-patches/2018-March/495853.html>). In a template, we should never create a FIX_TRUNC_EXPR (that's what conv_unsafe_in_template_p is for). But in this test we are NOT in a template when we call digest_nsdmi_init which ends up calling convert_like, converting 1.0e+0 to int, so convert_to_integer_1 gives us a FIX_TRUNC_EXPR. But then when we get to parsing f's parameters, we are in a template when processing decltype(Helpers{}), and since r268321, when the compound literal isn't instantiation-dependent and the type isn't type-dependent, finish_compound_literal falls back to the normal processing, so it calls digest_init, which does fold_non_dependent_init and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and therefore crash in tsubst_copy_and_build. The fateful call to fold_non_dependent_init comes from massage_init_elt, We shouldn't be calling f_n_d_i on the result of get_nsdmi. This we can avoid by eschewing calling f_n_d_i on CONSTRUCTORs; their elements have already been folded. PR c++/102990 gcc/cp/ChangeLog: * typeck2.cc (massage_init_elt): Avoid folding CONSTRUCTORs. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template22.C: New test. * g++.dg/cpp0x/nsdmi-template23.C: New test.
Fixed on trunk so far.
Do you know if the patch will be applied to the 10.x / 11.x branches ?
In any case many thanks for fixing this !
I was planning to backport the fix to 11, yes.
The releases/gcc-11 branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:6ba2a7e7474135b717c344030b114ffd6ad8ed7a commit r11-9711-g6ba2a7e7474135b717c344030b114ffd6ad8ed7a Author: Marek Polacek <polacek@redhat.com> Date: Tue Mar 22 18:42:27 2022 -0400 c++: FIX_TRUNC_EXPR in tsubst [PR102990] This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build where it hits gcc_unreachable (). The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it was introduced in r181478, but it did the wrong thing, whereupon it was turned into gcc_unreachable () in r258821 (see this thread: <https://gcc.gnu.org/pipermail/gcc-patches/2018-March/495853.html>). In a template, we should never create a FIX_TRUNC_EXPR (that's what conv_unsafe_in_template_p is for). But in this test we are NOT in a template when we call digest_nsdmi_init which ends up calling convert_like, converting 1.0e+0 to int, so convert_to_integer_1 gives us a FIX_TRUNC_EXPR. But then when we get to parsing f's parameters, we are in a template when processing decltype(Helpers{}), and since r268321, when the compound literal isn't instantiation-dependent and the type isn't type-dependent, finish_compound_literal falls back to the normal processing, so it calls digest_init, which does fold_non_dependent_init and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and therefore crash in tsubst_copy_and_build. The fateful call to fold_non_dependent_init comes from massage_init_elt, We shouldn't be calling f_n_d_i on the result of get_nsdmi. This we can avoid by eschewing calling f_n_d_i on CONSTRUCTORs; their elements have already been folded. PR c++/102990 gcc/cp/ChangeLog: * typeck2.c (massage_init_elt): Avoid folding CONSTRUCTORs. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template22.C: New test. * g++.dg/cpp0x/nsdmi-template23.C: New test. (cherry picked from commit f0530882d99abc410bb080051aa04e5cea848f18)
Fixed.