https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65154
Mikhail Maltsev <maltsevm at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |maltsevm at gmail dot com --- Comment #2 from Mikhail Maltsev <maltsevm at gmail dot com> --- I did some analysis of this bug, and want to share my results, though I still don't known, which part of the code should be fixed (and I'm asking for advice). ICE happens, when gimplifier tries to lower the constructor but gets some language specific expression. The function body looks like this (for the second test case, slightly modified: array contains one element): struct C cs[1]; struct C cs[1]; <<cleanup_point <<< Unknown tree: expr_stmt (void) (struct C[1] *) struct C * D.2137; <<< Unknown tree: expr_stmt (void) (D.2137 = (struct C *) &cs) >>>; struct C * D.2138; <<< Unknown tree: expr_stmt (void) (D.2138 = D.2137) >>>; long int D.2139; <<< Unknown tree: expr_stmt (void) (D.2139 = 0) >>>; while (1) { if (D.2139 == -1) goto <D.2150>; <<cleanup_point <<< Unknown tree: expr_stmt (void) (*D.2138 = {TARGET_EXPR <D.2140, <<< Unknown tree: aggr_init_expr 4 __comp_ctor D.2140 (struct ss *) <<< Unknown tree: void_cst >>> >>>>}) >>>>>; <<< Unknown tree: expr_stmt (void) ++D.2138 >>>; (void) --D.2139; } <D.2150>:; Here is a backtrace which leads to construction of such expression: #0 convert_like_real (convs=0x23f8820, expr=<target_expr 0x7ffff618b118>, fn=<tree 0x0>, argnum=0, inner=0, issue_conversion_warnings=true, c_cast_p=false, complain=3) at /home/miyuki/gcc/src/gcc/cp/call.c:6440 #1 0x00000000006c2e41 in perform_implicit_conversion_flags (type=<record_type 0x7ffff62d7690 ss>, expr=<constructor 0x7ffff62ec0d8>, complain=3, flags=5) at /home/miyuki/gcc/src/gcc/cp/call.c:9418 #2 0x0000000000856da8 in convert_for_initialization (exp=<tree 0x0>, type=<record_type 0x7ffff62d7690 ss>, rhs=<constructor 0x7ffff62ec0d8>, flags=5, errtype=ICR_INIT, fndecl=<tree 0x0>, parmnum=0, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck.c:8348 (continued, same call to convert_for_initialization as in previous backtrace) #5 0x0000000000856da8 in convert_for_initialization (exp=<tree 0x0>, type=<record_type 0x7ffff62d7690 ss>, rhs=<constructor 0x7ffff62ec0d8>, flags=5, errtype=ICR_INIT, fndecl=<tree 0x0>, parmnum=0, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck.c:8348 #6 0x000000000078a301 in digest_init_r (type=<record_type 0x7ffff62d7690 ss>, init=<constructor 0x7ffff62ec0d8>, nested=true, flags=5, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck2.c:1126 #7 0x000000000078a5ef in massage_init_elt (type=<record_type 0x7ffff62d7690 ss>, init=<constructor 0x7ffff62ec0d8>, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck2.c:1190 #8 0x000000000078b4dd in process_init_constructor_record (type=<record_type 0x7ffff62d7d20 C>, init=<constructor 0x7ffff62dffc0>, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck2.c:1395 #9 0x000000000078beb1 in process_init_constructor (type=<record_type 0x7ffff62d7d20 C>, init=<constructor 0x7ffff62dffc0>, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck2.c:1562 #10 0x000000000078a159 in digest_init_r (type=<record_type 0x7ffff62d7d20 C>, init=<constructor 0x7ffff62dffc0>, nested=false, flags=5, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck2.c:1094 #11 0x000000000078a336 in digest_init (type=<record_type 0x7ffff62d7d20 C>, init=<constructor 0x7ffff62dffc0>, complain=3) at /home/miyuki/gcc/src/gcc/cp/typeck2.c:1133 #12 0x000000000086d81d in expand_default_init (binfo=<tree_binfo 0x7ffff62da600>, true_exp=<indirect_ref 0x7ffff62ed0a0>, exp=<indirect_ref 0x7ffff62ed0a0>, init=<constructor 0x7ffff62dffc0>, flags=1, complain=3) #13 0x000000000086e4f3 in expand_aggr_init_1 (binfo=<tree_binfo 0x7ffff62da600>, true_exp=<indirect_ref 0x7ffff62ed0a0>, exp=<indirect_ref 0x7ffff62ed0a0>, init=<constructor 0x7ffff62dffc0>, flags=1, complain=3) at /home/miyuki/gcc/src/gcc/cp/init.c:1830 #14 0x000000000086d431 in build_aggr_init (exp=<indirect_ref 0x7ffff62ed0a0>, init=<constructor 0x7ffff62dffc0>, flags=0, complain=3) at /home/miyuki/gcc/src/gcc/cp/init.c:1582 #15 0x000000000087493d in build_vec_init (base=<var_decl 0x7ffff62eb120>, maxindex=<integer_cst 0x7ffff62dffd8>, init=<constructor 0x7ffff62dffc0>, explicit_value_init_p=false, from_array=0, complain=3) at /home/miyuki/gcc/src/gcc/cp/init.c:3777 #16 0x000000000086d271 in build_aggr_init (exp=<var_decl 0x7ffff62eb000 cs>, init=<constructor 0x7ffff62dffc0>, flags=2049, complain=3) at /home/miyuki/gcc/src/gcc/cp/init.c:1563 #17 0x00000000006e192d in build_aggr_init_full_exprs (decl=<var_decl 0x7ffff62eb000 cs>, init=<constructor 0x7ffff62dffc0>, flags=2049) at /home/miyuki/gcc/src/gcc/cp/decl.c:5811 build_vec_init creates the loop, which performs elemtwise initialization of the array. It is initialized with the same entity (direct initializer - here it is seen as <constructor 0x7ffff62dffc0>) as the whole array. Then some strange overload resolution is performed, which eventually gets resolved to the user-defined default constructor (If I understood that right) and conversion is applied to initializer before the call (which does not make sence). Obviously the initializer must become "void" somewhere, but I don't known what's the appropriate place for it. For example, some similar code (for handling zero-initialization) is present in build_aggr_init, but this case can't be handled there (because overload resolution must be performed, for a case when class s has a constructor which accepts std::initializer_list).