On Mon, Jun 10, 2019 at 09:59:46PM -0400, Marek Polacek wrote:
> This test segvs since r269078, this hunk in particular:
>
> @@ -4581,8 +4713,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx,
> tree t,
> break;
>
> case SIZEOF_EXPR:
> - r = fold_sizeof_expr (t);
> - VERIFY_CONSTANT (r);
> + r = cxx_eval_constant_expression (ctx, fold_sizeof_expr (t), lval,
> + non_constant_p, overflow_p,
> + jump_target);
> break;
>
> In a template, fold_sizeof_expr will just create a new SIZEOF_EXPR, that is
> the
> same, but not identical; see cxx_sizeof_expr. Then
> cxx_eval_constant_expression
Not always, if it calls cxx_sizeof_expr, it will, but if it calls
cxx_sizeof_or_alignof_type it will only if the type is dependent or VLA.
So, I'd think you should call cxx_eval_constant_expression if TREE_CODE (r)
!= SIZEOF_EXPR, otherwise probably *non_constant_p = true; is in order,
maybe together with gcc_assert (ctx->quiet); ? I'd hope that if we really
require a constant expression we evaluate it in !processing_template_decl
contexts.
> case SIZEOF_EXPR:
> - r = cxx_eval_constant_expression (ctx, fold_sizeof_expr (t), lval,
> - non_constant_p, overflow_p,
> - jump_target);
> + r = fold_sizeof_expr (t);
> + /* Don't recurse in a template, because then fold_sizeof_expr merely
> + creates a new SIZEOF_EXPR, leading to an infinite recursion. */
> + if (!processing_template_decl)
> + r = cxx_eval_constant_expression (ctx, r, lval,
> + non_constant_p, overflow_p,
> + jump_target);
> break;
Jakub