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

Reply via email to