Bug 102990 - [9/10 Regression] ICE in tsubst_copy_and_build with NSDMI and double to int conversion
Summary: [9/10 Regression] ICE in tsubst_copy_and_build with NSDMI and double to int c...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.1.0
: P2 normal
Target Milestone: 9.5
Assignee: Marek Polacek
URL:
Keywords: ice-on-invalid-code, ice-on-valid-code
: 103019 104720 (view as bug list)
Depends on: 105256
Blocks:
  Show dependency treegraph
 
Reported: 2021-10-28 18:19 UTC by Jean-Michaël Celerier
Modified: 2022-04-19 08:38 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 8.5.0
Known to fail: 10.3.0, 11.2.0, 12.0, 9.4.0
Last reconfirmed: 2021-11-01 00:00:00


Attachments
Source code that causes the ICE (583.14 KB, application/gzip)
2021-10-28 18:19 UTC, Jean-Michaël Celerier
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jean-Michaël Celerier 2021-10-28 18:19:55 UTC
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
Comment 1 Andrew Pinski 2021-10-31 09:35:59 UTC
Reducing.
Comment 2 Andrew Pinski 2021-10-31 23:22:25 UTC
Still reducing it, down to 2.2M file
Comment 3 Andrew Pinski 2021-11-01 09:25:28 UTC
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>{});
Comment 4 Andrew Pinski 2021-11-01 09:26:42 UTC
*** Bug 103019 has been marked as a duplicate of this bug. ***
Comment 5 Andrew Pinski 2021-11-01 09:28:31 UTC
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>();
Comment 6 Patrick Palka 2021-11-01 12:58:49 UTC
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)
Comment 7 Marek Polacek 2021-11-01 17:40:58 UTC
Oof, mine then.  Thanks for reducing this.
Comment 8 Andrew Pinski 2022-03-01 06:24:17 UTC
*** Bug 104720 has been marked as a duplicate of this bug. ***
Comment 9 GCC Commits 2022-03-24 17:12:50 UTC
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.
Comment 10 Marek Polacek 2022-03-24 17:13:24 UTC
Fixed on trunk so far.
Comment 11 Jean-Michaël Celerier 2022-03-28 14:15:32 UTC
Do you know if the patch will be applied to the 10.x / 11.x branches ?
Comment 12 Jean-Michaël Celerier 2022-03-28 14:16:03 UTC
In any case many thanks for fixing this !
Comment 13 Marek Polacek 2022-03-28 14:19:46 UTC
I was planning to backport the fix to 11, yes.
Comment 14 GCC Commits 2022-03-29 01:44:53 UTC
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)
Comment 15 Marek Polacek 2022-03-29 01:47:46 UTC
Fixed.