https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88572

--- Comment #12 from Will Wray <wjwray at gmail dot com> ---
On further investigation the logic of using first_initializer_p looks correct.

The comment on reshape_init suggests that it wasn't intended for scalar init:

 /* Undo the brace-elision allowed by [dcl.init.aggr] in a
    brace-enclosed aggregate initializer.

    INIT is the CONSTRUCTOR containing the list of initializers describing
    a brace-enclosed initializer for an entity of the indicated aggregate TYPE.

In fact, reshape_init is used more broadly to error-check braced-init-list -
- the first substantive case is direct enum init, a scalar init special-case.
Perhaps the general scalar case should be dealt with here at the top level.
Instead the recursive call to reshape_init_r is done next
setting first_initializer_p to true - the only place it is set true
(the true value will be forwarded to reshape_init_class for class type).

So, for a scalar init, the tree type passed to reshape_init is SCALAR_TYPE_P.
This is passed down to reshape_init_r with first_initializer_p set true.

Entering reshape_init_r we have

  if (first_initializer_p && !CP_AGGREGATE_TYPE_P (type)
      && has_designator_problem (d, complain))
    return error_mark_node;

Here, first_initializer_p && !CP_AGGREGATE_TYPE_P (type) covers scalar init
(and other non-aggregate init).

Arriving at our block, we also enter a context requiring a single-initializer

  /* A non-aggregate type is always initialized with a single
     initializer.  */
  if (!CP_AGGREGATE_TYPE_P (type))

and then further filter down to CONSTRUCTOR with BRACE_ENCLOSED_INITIALIZER_P
and, specifically of SCALAR_TYPE_P

      if (TREE_CODE (stripped_init) == CONSTRUCTOR
          /* Don't complain about a capture-init.  */
          && !CONSTRUCTOR_IS_DIRECT_INIT (stripped_init)
          && BRACE_ENCLOSED_INITIALIZER_P (stripped_init))  /* p7626.C */
        {
          if (SCALAR_TYPE_P (type))


> I understood it to mean something like {{1}, 2} is the first,
>                                         ^^^

Me too, but taking "outermost CONSTRUCTOR node" to mean the actual outer type
here (first_initializer_p==true) and with only a single scalar initializer:

  like scalar_type{{1}}    not {           {1} }
                   ^^^          scalar_type^^^

So, I've convinced myself that my patch follows the existing logic.
It'd be good to get review from someone not suffering from confirmation bias.

Reply via email to