OK.

On Fri, Mar 2, 2018 at 12:36 PM, Marek Polacek <pola...@redhat.com> wrote:
> We ICE in cxx_eval_vec_init_1 whereby we try to initialize a flexible array
> member, because the code computing the number of elements of ATYPE wasn't
> prepared to handle arrays with no bounds.  Fixed by using
> get_array_or_vector_nelts, broken out of existing code.
>
> Martin suggested to reject this code, but I decided to leave this as-is for
> now; we already reject code that actually tries to initialize the flexible
> array member with some data, e.g.:
>
> struct A {
>   constexpr A() : i(), x("foo") {}
>   int i;
>   char x[];
> };
> A a;
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-03-02  Marek Polacek  <pola...@redhat.com>
>
>         PR c++/84578
>         * constexpr.c (get_array_or_vector_nelts): New.
>         (cxx_eval_array_reference): Use it.
>         (cxx_eval_vec_init_1): Likewise.
>         (cxx_eval_store_expression): Likewise.
>
>         * g++.dg/ext/flexary29.C: New test.
>
> diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
> index 39e6cdfb33d..27f841db38f 100644
> --- gcc/cp/constexpr.c
> +++ gcc/cp/constexpr.c
> @@ -2300,6 +2300,32 @@ diag_array_subscript (const constexpr_ctx *ctx, tree 
> array, tree index)
>      }
>  }
>
> +/* Return the number of elements for TYPE (which is an ARRAY_TYPE or
> +   a VECTOR_TYPE).  */
> +
> +static tree
> +get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
> +                          bool *non_constant_p, bool *overflow_p)
> +{
> +  tree nelts;
> +  if (TREE_CODE (type) == ARRAY_TYPE)
> +    {
> +      if (TYPE_DOMAIN (type))
> +       nelts = array_type_nelts_top (type);
> +      else
> +       nelts = size_zero_node;
> +    }
> +  else if (VECTOR_TYPE_P (type))
> +    nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
> +  else
> +    gcc_unreachable ();
> +
> +  /* For VLAs, the number of elements won't be an integer constant.  */
> +  nelts = cxx_eval_constant_expression (ctx, nelts, false,
> +                                       non_constant_p, overflow_p);
> +  return nelts;
> +}
> +
>  /* Extract element INDEX consisting of CHARS_PER_ELT chars from
>     STRING_CST STRING.  */
>
> @@ -2379,22 +2405,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, 
> tree t,
>         }
>      }
>
> -  tree nelts;
> -  if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
> -    {
> -      if (TYPE_DOMAIN (TREE_TYPE (ary)))
> -       nelts = array_type_nelts_top (TREE_TYPE (ary));
> -      else
> -       nelts = size_zero_node;
> -    }
> -  else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
> -    nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
> -  else
> -    gcc_unreachable ();
> -
> -  /* For VLAs, the number of elements won't be an integer constant.  */
> -  nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
> -                                       overflow_p);
> +  tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), 
> non_constant_p,
> +                                         overflow_p);
>    VERIFY_CONSTANT (nelts);
>    if ((lval
>         ? !tree_int_cst_le (index, nelts)
> @@ -2895,7 +2907,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree 
> atype, tree init,
>                      bool *non_constant_p, bool *overflow_p)
>  {
>    tree elttype = TREE_TYPE (atype);
> -  unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype));
>    verify_ctor_sanity (ctx, atype);
>    vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
>    bool pre_init = false;
> @@ -2924,6 +2935,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree 
> atype, tree init,
>        pre_init = true;
>      }
>
> +  tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
> +                                         overflow_p);
> +  unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
>    for (i = 0; i < max; ++i)
>      {
>        tree idx = build_int_cst (size_type_node, i);
> @@ -3480,19 +3494,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, 
> tree t,
>         case ARRAY_REF:
>           tree nelts, ary;
>           ary = TREE_OPERAND (probe, 0);
> -         if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
> -           {
> -             if (TYPE_DOMAIN (TREE_TYPE (ary)))
> -               nelts = array_type_nelts_top (TREE_TYPE (ary));
> -             else
> -               nelts = size_zero_node;
> -           }
> -         else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
> -           nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
> -         else
> -           gcc_unreachable ();
> -         nelts = cxx_eval_constant_expression (ctx, nelts, false,
> -                                               non_constant_p, overflow_p);
> +         nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary),
> +                                            non_constant_p, overflow_p);
>           VERIFY_CONSTANT (nelts);
>           gcc_assert (TREE_CODE (nelts) == INTEGER_CST
>                       && TREE_CODE (TREE_OPERAND (probe, 1)) == INTEGER_CST);
> diff --git gcc/testsuite/g++.dg/ext/flexary29.C 
> gcc/testsuite/g++.dg/ext/flexary29.C
> index e69de29bb2d..a696fd9804f 100644
> --- gcc/testsuite/g++.dg/ext/flexary29.C
> +++ gcc/testsuite/g++.dg/ext/flexary29.C
> @@ -0,0 +1,12 @@
> +// PR c++/84578
> +// { dg-do compile { target c++11 } }
> +// { dg-options -Wno-pedantic }
> +
> +struct A
> +{
> +  constexpr A() : i(), x() {}
> +  int i;
> +  char x[];
> +};
> +
> +A a;
>
>         Marek

Reply via email to