On Thu, Oct 28, 2021 at 08:01:27AM -0400, Jason Merrill wrote: > > --- gcc/cp/semantics.c.jj 2021-10-27 09:16:41.161600606 +0200 > > +++ gcc/cp/semantics.c 2021-10-28 13:06:59.325791588 +0200 > > @@ -3079,6 +3079,24 @@ finish_unary_op_expr (location_t op_loc, > > return result; > > } > > +/* Return true if CONSTRUCTOR EXPR after pack expansion could have no > > + elements. */ > > + > > +static bool > > +maybe_zero_constructor_nelts (tree expr) > > +{ > > + if (CONSTRUCTOR_NELTS (expr) == 0) > > + return true; > > + if (!processing_template_decl) > > + return false; > > + unsigned int i; > > + tree val; > > + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, val) > > Let's use > > for (constructor_elt &elt : CONSTRUCTOR_ELTS (t))
Ok, will do. > > @@ -3104,9 +3122,20 @@ finish_compound_literal (tree type, tree > > if (!TYPE_OBJ_P (type)) > > { > > - if (complain & tf_error) > > - error ("compound literal of non-object type %qT", type); > > - return error_mark_node; > > + /* DR2351 */ > > + if (VOID_TYPE_P (type) && CONSTRUCTOR_NELTS (compound_literal) == 0) > > + return void_node; > > This test now seems redundant with the one below (if you remove the && > processing_template_decl). It is not redundant, for the maybe case it doesn't return void_node, but falls through into if (processing_template_decl), which, because compound_literal is necessarily instantiation_dependent_expression_p (it contains packs) will just create CONSTRUCTOR_IS_DEPENDENT CONSTRUCTOR and we'll get here back during instantiation. For the CONSTRUCTOR_NELTS == 0 case even in templates we know compound_literal isn't dependent (it doesn't contain anything) and type isn't either, so we can return void_node right away (and when !processing_template_decl we have to do that). Jakub