On Thu, Jan 31, 2019 at 12:32 PM Marek Polacek <pola...@redhat.com> wrote: > On Thu, Jan 31, 2019 at 10:17:54AM -0500, Jason Merrill wrote: > > On 1/31/19 9:50 AM, Marek Polacek wrote: > > > On Wed, Jan 30, 2019 at 05:37:13PM -0500, Jason Merrill wrote: > > > > On 1/30/19 4:15 PM, Marek Polacek wrote: > > > > > On Wed, Jan 30, 2019 at 04:11:11PM -0500, Marek Polacek wrote: > > > > > > On Tue, Jan 29, 2019 at 09:40:18PM -0500, Jason Merrill wrote: > > > > > > > On Tue, Jan 29, 2019 at 6:53 PM Marek Polacek > > > > > > > <pola...@redhat.com> wrote: > > > > > > > > > > > > > > > > My recent patch for 88815 and 78244 caused 89083, a P1 9 > > > > > > > > regression, which > > > > > > > > happens to be the same problem as 80864 and its many dupes, > > > > > > > > something I'd > > > > > > > > been meaning to fix for a long time. > > > > > > > > > > > > > > > > Basically, the problem is repeated reshaping of a constructor, > > > > > > > > once when > > > > > > > > parsing, and then again when substituting. With the recent > > > > > > > > fix, we call > > > > > > > > reshape_init + digest_init in finish_compound_literal even in a > > > > > > > > template > > > > > > > > if the expression is not instantiation-dependent, and then > > > > > > > > again when > > > > > > > > tsubst_*. > > > > > > > > > > > > > > > > For instance, in initlist107.C, when parsing a functional cast, > > > > > > > > we call > > > > > > > > finish_compound_literal which calls reshape_init, which turns > > > > > > > > > > > > > > > > { NON_LVALUE_EXPR<1>, NON_LVALUE_EXPR<2> } > > > > > > > > > > > > > > > > into > > > > > > > > > > > > > > > > { { NON_LVALUE_EXPR<1>, NON_LVALUE_EXPR<2> } } > > > > > > > > > > > > > > > > and then digest_init turns that into > > > > > > > > > > > > > > > > { .x = { 1, 2 } } > > > > > > > > > > > > > > > > which is a compound literal (TREE_HAS_CONSTRUCTOR set), but the > > > > > > > > subexpression > > > > > > > > "{ 1, 2 }" isn't. "{ 1, 2 }" will now have the type int[3], so > > > > > > > > it's not > > > > > > > > BRACE_ENCLOSED_INITIALIZER_P. > > > > > > > > > > > > > > > > And then tsubst_* processes "{ .x = { 1, 2 } }". The case > > > > > > > > CONSTRUCTOR > > > > > > > > in tsubst_copy_and_build will call finish_compound_literal on a > > > > > > > > copy of > > > > > > > > "{ 1, 2 }" wrapped in a new { }, because the whole expr has > > > > > > > > TREE_HAS_CONSTRUCTOR. > > > > > > > > That crashes in reshape_init_r in the > > > > > > > > 6155 if (TREE_CODE (stripped_init) == CONSTRUCTOR) > > > > > > > > block; we have a constructor, it's not COMPOUND_LITERAL_P, and > > > > > > > > because > > > > > > > > digest_init had given it the type int[3], we hit > > > > > > > > 6172 gcc_assert (BRACE_ENCLOSED_INITIALIZER_P > > > > > > > > (stripped_init)); > > > > > > > > > > > > > > > > As expand_default_init explains in a comment, a CONSTRUCTOR of > > > > > > > > the target's type > > > > > > > > is a previously digested initializer, so we should probably do > > > > > > > > a similar trick > > > > > > > > here. This fixes all the variants of the problem I've come up > > > > > > > > with. > > > > > > > > > > > > > > > > 80864 is a similar case, we reshape when parsing and then > > > > > > > > second time in > > > > > > > > fold_non_dependent_expr called from store_init_value, because > > > > > > > > of the 'constexpr'. > > > > > > > > > > > > > > > > Also update a stale comment. > > > > > > > > > > > > > > > > Bootstrapped/regtest running on x86_64-linux, ok for trunk and > > > > > > > > 8 after a while? > > > > > > > > > > > > > > > > 2019-01-29 Marek Polacek <pola...@redhat.com> > > > > > > > > > > > > > > > > PR c++/89083, c++/80864 - ICE with list > > > > > > > > initialization in template. > > > > > > > > * decl.c (reshape_init_r): Don't reshape a digested > > > > > > > > initializer. > > > > > > > > > > > > > > > > * g++.dg/cpp0x/initlist107.C: New test. > > > > > > > > * g++.dg/cpp0x/initlist108.C: New test. > > > > > > > > * g++.dg/cpp0x/initlist109.C: New test. > > > > > > > > > > > > > > > > diff --git gcc/cp/decl.c gcc/cp/decl.c > > > > > > > > index 79eeac177b6..da08ecc21aa 100644 > > > > > > > > --- gcc/cp/decl.c > > > > > > > > +++ gcc/cp/decl.c > > > > > > > > @@ -6161,11 +6161,17 @@ reshape_init_r (tree type, reshape_iter > > > > > > > > *d, bool first_initializer_p, > > > > > > > > ; > > > > > > > > else if (COMPOUND_LITERAL_P (stripped_init)) > > > > > > > > /* For a nested compound literal, there is no need > > > > > > > > to reshape since > > > > > > > > - brace elision is not allowed. Even if we decided > > > > > > > > to allow it, > > > > > > > > - we should add a call to reshape_init in > > > > > > > > finish_compound_literal, > > > > > > > > - before calling digest_init, so changing this code > > > > > > > > would still > > > > > > > > - not be necessary. */ > > > > > > > > + we called reshape_init in finish_compound_literal, > > > > > > > > before calling > > > > > > > > + digest_init. */ > > > > > > > > gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P > > > > > > > > (stripped_init)); > > > > > > > > + /* Similarly, a CONSTRUCTOR of the target's type is a > > > > > > > > previously > > > > > > > > + digested initializer. */ > > > > > > > > + else if (same_type_ignoring_top_level_qualifiers_p > > > > > > > > (type, > > > > > > > > + > > > > > > > > TREE_TYPE (init))) > > > > > > > > > > > > > > Hmm, aren't both of these tests true for a dependent compound > > > > > > > literal, > > > > > > > which won't have been reshaped already? > > > > > > > > > > > > I'm hoping that can't happen, but it's a good question. When we > > > > > > have a > > > > > > dependent compound literal, finish_compound_literal just sets > > > > > > TREE_HAS_CONSTRUCTOR and returns it, so then in tsubst_*, after > > > > > > substituting > > > > > > each element of the constructor, we call finish_compound_literal. > > > > > > The > > > > > > constructor is no longer dependent and since we operate on a copy > > > > > > on which > > > > > > we didn't set TREE_HAS_CONSTRUCTOR, the first condition shouldn't > > > > > > be true. > > > > > > > > > > > > And the second condition should also never be true for a compound > > > > > > literal > > > > > > that hasn't been reshaped, because digest_init is only ever called > > > > > > after > > > > > > reshape_init (and the comment for digest_init_r says it assumes that > > > > > > reshape_init has already run). > > > > > > > > And because, as above, tsubst_* builds up a CONSTRUCTOR with > > > > init_list_type_node and feeds that to finish_compound_literal. > > > > > > Yes. > > > > > > > I suppose that means we do the same thing for a non-dependent > > > > CONSTRUCTOR > > > > that has already been reshaped, but it should be harmless. > > > > > > > > > > The type of a CONSTRUCTOR can also by changed > > > > > > in tsubst_copy_and_build: > > > > > > 19269 TREE_TYPE (r) = type; > > > > > > but I haven't been able to trigger any problem yet. Worst comes to > > > > > > worst this > > > > > > patch changes the ICE to another ICE, but I'm not finding a > > > > > > testcase. > > > > > > > > I'd expect that's where the { 1, 2 } goes through to produce this issue. > > > > > > Correct. There's more to this. When I debugged 80864 I couldn't > > > understand > > > why r216750 would make any difference here, why the type in the case > > > CONSTRUCTOR was not an init list type. It turned out that the reason was > > > the new > > > if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)) > > > ... > > > > > > block in cxx_eval_outermost_constant_expr added in r216750, because it > > > does > > > > > > if (TREE_CODE (r) == TARGET_EXPR) > > > /* Avoid creating another CONSTRUCTOR when we expand the > > > TARGET_EXPR. */ > > > r = TARGET_EXPR_INITIAL (r); > > > > > > Before r216750 we'd process the TARGET_EXPR in > > > cxx_eval_constant_expression, > > > and that has > > > > > > 4422 /* Adjust the type of the result to the type of the > > > temporary. */ > > > 4423 r = adjust_temp_type (TREE_TYPE (t), r); > > > > > > whereas now we extract the CONSTRUCTOR from the TARGET_EXPR, and we end up > > > doing > > > > > > 5176 if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r))) > > > 5177 { > > > 5178 r = adjust_temp_type (type, r); > > > > > > Now "type" here was obtained by initialized_type, which always uses > > > cv_unqualified. So while "TREE_TYPE (t)" is const something, "type" is > > > without that const. And look what adjust_temp_type does: > > > > > > 1290 if (same_type_p (TREE_TYPE (temp), type)) > > > 1291 return temp; > > > 1292 /* Avoid wrapping an aggregate value in a NOP_EXPR. */ > > > 1293 if (TREE_CODE (temp) == CONSTRUCTOR) > > > 1294 return build_constructor (type, CONSTRUCTOR_ELTS (temp)); > > > > > > So if I remember correctly in one case we returned the original ctor with > > > TREE_HAS_CONSTRUCTOR preserved, and in the other case we returned a new > > > ctor > > > without TREE_HAS_CONSTRUCTOR. > > > > > Now I still think my fix makes sense, but the above is suspicious, too. > > > (Using initialized_type instead of "TREE_TYPE (t)" doesn't fix this bug.) > > > > Hmm, that does look questionable; adjust_temp_type should probably use > > copy_node (and then change the type) rather than build_constructor. Does > > doing that also fix the bug? Having that flag would mean COMPOUND_LITERAL_P > > is true, so adding the same_type check shouldn't be necessary. > > Ok, so that doesn't help at all -- I guess because we now use initialized_type > without cv-quals, the same_type_p check applies and adjust_temp_type returns > the original expression, so it's not the case that we're losing the > TREE_HAS_CONSTRUCTOR bit here. > > For initlist107.C we don't call adjust_temp_type at all. > > > > > Hmm, the PMF and nested compound literal cases above your change look > > > > like > > > > they don't do what they're intended to do; they fall through to either > > > > gcc_unreachable or reshape_init_*, contrary to the comments. > > > > > > Things break if I return in the PMF case, we need to keep it as-is. I've > > > updated its comment though. And I've added a new test checking "missing > > > braces" for a PMF. It matches what clang warns about. > > > > > > But I merged my new case with the nested compound literal case and that > > > doesn't seem to break anything. > > > > > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > > > > > 2019-01-31 Marek Polacek <pola...@redhat.com> > > > > > > PR c++/89083, c++/80864 - ICE with list initialization in template. > > > * decl.c (reshape_init_r): Don't reshape a digested initializer. > > > Return the initializer for COMPOUND_LITERAL_P. > > > > > > * g++.dg/cpp0x/initlist107.C: New test. > > > * g++.dg/cpp0x/initlist108.C: New test. > > > * g++.dg/cpp0x/initlist109.C: New test. > > > * g++.dg/cpp0x/initlist110.C: New test. > > > * g++.dg/cpp0x/initlist111.C: New test. > > > * g++.dg/cpp0x/initlist112.C: New test. > > > * g++.dg/init/ptrfn4.C: New test. > > > > > > diff --git gcc/cp/decl.c gcc/cp/decl.c > > > index 79eeac177b6..de4883ff994 100644 > > > --- gcc/cp/decl.c > > > +++ gcc/cp/decl.c > > > @@ -6154,20 +6154,29 @@ reshape_init_r (tree type, reshape_iter *d, bool > > > first_initializer_p, > > > { > > > if (TREE_CODE (stripped_init) == CONSTRUCTOR) > > > { > > > - if (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init))) > > > - /* There is no need to reshape pointer-to-member function > > > - initializers, as they are always constructed correctly > > > - by the front end. */ > > > - ; > > > - else if (COMPOUND_LITERAL_P (stripped_init)) > > > + tree init_type = TREE_TYPE (init); > > > + if (init_type && TYPE_PTRMEMFUNC_P (init_type)) > > > + /* There is no need to call reshape_init forpointer-to-member > > > > Missing space. > > Fixed. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2019-01-31 Marek Polacek <pola...@redhat.com> > > PR c++/89083, c++/80864 - ICE with list initialization in template. > * constexpr.c (adjust_temp_type): Use copy_node and change the type > instead of using build_constructor. > * decl.c (reshape_init_r): Don't reshape a digested initializer. > Return the initializer for COMPOUND_LITERAL_P.
OK.