OK.

On Wed, May 23, 2018 at 4:27 PM, Marek Polacek <pola...@redhat.com> wrote:
> On Wed, May 23, 2018 at 03:24:20PM -0400, Jason Merrill wrote:
>> On Wed, May 23, 2018 at 2:50 PM, Marek Polacek <pola...@redhat.com> wrote:
>> > On Wed, May 23, 2018 at 12:45:11PM -0400, Jason Merrill wrote:
>> >> On Wed, May 23, 2018 at 9:46 AM, Marek Polacek <pola...@redhat.com> wrote:
>> >> > The diagnostic code in build_new{,_1} was using maybe_constant_value to 
>> >> > fold
>> >> > the array length, but that breaks while parsing a template, because we 
>> >> > might
>> >> > then leak template codes to the constexpr machinery.
>> >> >
>> >> > Bootstrapped/regtested on x86_64-linux, ok for trunk/8?
>> >> >
>> >> > 2018-05-23  Marek Polacek  <pola...@redhat.com>
>> >> >
>> >> >         PR c++/85847
>> >> >         * init.c (build_new_1): Use fold_non_dependent_expr.
>> >> >         (build_new): Likewise.
>> >> >
>> >> >         * g++.dg/cpp0x/new3.C: New test.
>> >> >
>> >> > @@ -2860,7 +2860,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree 
>> >> > type, tree nelts,
>> >> >    /* Lots of logic below. depends on whether we have a constant number 
>> >> > of
>> >> >       elements, so go ahead and fold it now.  */
>> >> >    if (outer_nelts)
>> >> > -    outer_nelts = maybe_constant_value (outer_nelts);
>> >> > +    outer_nelts = fold_non_dependent_expr (outer_nelts);
>> >>
>> >> If outer_nelts is non-constant, this will mean that it ends up
>> >> instantiated but still non-constant, which can lead to problems when
>> >> the result is used in building up other expressions.
>> >>
>> >> I think we want to put the result of folding in a separate variable
>> >> for use with things that want to know about a constant size, and keep
>> >> the original outer_nelts for use in building outer_nelts_check.
>> >>
>> >> >        /* Try to determine the constant value only for the purposes
>> >> >          of the diagnostic below but continue to use the original
>> >> >          value and handle const folding later.  */
>> >> > -      const_tree cst_nelts = maybe_constant_value (nelts);
>> >> > +      const_tree cst_nelts = fold_non_dependent_expr (nelts);
>> >>
>> >> ...like we do here.
>> >
>> > Like this?
>> >
>> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
>> >
>> > 2018-05-23  Marek Polacek  <pola...@redhat.com>
>> >
>> >         PR c++/85847
>> >         * init.c (build_new_1): Use fold_non_dependent_expr.  Use a 
>> > dedicated
>> >         variable for its result.  Fix a condition.
>> >         (build_new): Use fold_non_dependent_expr.  Tweak a condition.
>> >
>> >         * g++.dg/cpp0x/new3.C: New test.
>> >
>> > diff --git gcc/cp/init.c gcc/cp/init.c
>> > index b558742abf6..cd0110a1e19 100644
>> > --- gcc/cp/init.c
>> > +++ gcc/cp/init.c
>> > @@ -2857,10 +2857,9 @@ build_new_1 (vec<tree, va_gc> **placement, tree 
>> > type, tree nelts,
>> >        outer_nelts_from_type = true;
>> >      }
>> >
>> > -  /* Lots of logic below. depends on whether we have a constant number of
>> > +  /* Lots of logic below depends on whether we have a constant number of
>> >       elements, so go ahead and fold it now.  */
>> > -  if (outer_nelts)
>> > -    outer_nelts = maybe_constant_value (outer_nelts);
>> > +  const_tree cst_outer_nelts = fold_non_dependent_expr (outer_nelts);
>> >
>> >    /* If our base type is an array, then make sure we know how many 
>> > elements
>> >       it has.  */
>> > @@ -2912,11 +2911,12 @@ build_new_1 (vec<tree, va_gc> **placement, tree 
>> > type, tree nelts,
>> >    /* Warn if we performed the (T[N]) to T[N] transformation and N is
>> >       variable.  */
>> >    if (outer_nelts_from_type
>> > -      && !TREE_CONSTANT (outer_nelts))
>> > +      && cst_outer_nelts != NULL_TREE
>> > +      && !TREE_CONSTANT (cst_outer_nelts))
>>
>> Why add the comparisons with NULL_TREE?  fold_non_dependent_expr only
>> returns null if its argument is null.
>
> True, and it seemed to me that the argument can be null when NELTS is null,
> which, according to the comment for build_new_1 could happen.  So I was just
> being cautious.  But I dropped the checks and nothing in the testsuite broke.
>
>> > -         pedwarn (EXPR_LOC_OR_LOC (outer_nelts, input_location), OPT_Wvla,
>> > +         pedwarn (EXPR_LOC_OR_LOC (cst_outer_nelts, input_location), 
>> > OPT_Wvla,
>>
>> Let's drop this change, the original expression has the location we want.
>
> Okay.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk/8?
>
> 2018-05-23  Marek Polacek  <pola...@redhat.com>
>
>         PR c++/85847
>         * init.c (build_new_1): Use fold_non_dependent_expr.  Use a dedicated
>         variable for its result.  Fix a condition.
>         (build_new): Use fold_non_dependent_expr.  Tweak a condition.
>
>         * g++.dg/cpp0x/new3.C: New test.
>
> diff --git gcc/cp/init.c gcc/cp/init.c
> index b558742abf6..5bfd0848fc4 100644
> --- gcc/cp/init.c
> +++ gcc/cp/init.c
> @@ -2857,10 +2857,9 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, 
> tree nelts,
>        outer_nelts_from_type = true;
>      }
>
> -  /* Lots of logic below. depends on whether we have a constant number of
> +  /* Lots of logic below depends on whether we have a constant number of
>       elements, so go ahead and fold it now.  */
> -  if (outer_nelts)
> -    outer_nelts = maybe_constant_value (outer_nelts);
> +  const_tree cst_outer_nelts = fold_non_dependent_expr (outer_nelts);
>
>    /* If our base type is an array, then make sure we know how many elements
>       it has.  */
> @@ -2912,7 +2911,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, 
> tree nelts,
>    /* Warn if we performed the (T[N]) to T[N] transformation and N is
>       variable.  */
>    if (outer_nelts_from_type
> -      && !TREE_CONSTANT (outer_nelts))
> +      && !TREE_CONSTANT (cst_outer_nelts))
>      {
>        if (complain & tf_warning_or_error)
>         {
> @@ -3011,9 +3010,9 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, 
> tree nelts,
>
>        size = size_binop (MULT_EXPR, size, fold_convert (sizetype, nelts));
>
> -      if (INTEGER_CST == TREE_CODE (outer_nelts))
> +      if (TREE_CODE (cst_outer_nelts) == INTEGER_CST)
>         {
> -         if (tree_int_cst_lt (max_outer_nelts_tree, outer_nelts))
> +         if (tree_int_cst_lt (max_outer_nelts_tree, cst_outer_nelts))
>             {
>               /* When the array size is constant, check it at compile time
>                  to make sure it doesn't exceed the implementation-defined
> @@ -3639,13 +3638,13 @@ build_new (vec<tree, va_gc> **placement, tree type, 
> tree nelts,
>        /* Try to determine the constant value only for the purposes
>          of the diagnostic below but continue to use the original
>          value and handle const folding later.  */
> -      const_tree cst_nelts = maybe_constant_value (nelts);
> +      const_tree cst_nelts = fold_non_dependent_expr (nelts);
>
>        /* The expression in a noptr-new-declarator is erroneous if it's of
>          non-class type and its value before converting to std::size_t is
>          less than zero. ... If the expression is a constant expression,
>          the program is ill-fomed.  */
> -      if (INTEGER_CST == TREE_CODE (cst_nelts)
> +      if (TREE_CODE (cst_nelts) == INTEGER_CST
>           && tree_int_cst_sgn (cst_nelts) == -1)
>         {
>           if (complain & tf_error)
> diff --git gcc/testsuite/g++.dg/cpp0x/new3.C gcc/testsuite/g++.dg/cpp0x/new3.C
> index e69de29bb2d..c388acf552e 100644
> --- gcc/testsuite/g++.dg/cpp0x/new3.C
> +++ gcc/testsuite/g++.dg/cpp0x/new3.C
> @@ -0,0 +1,11 @@
> +// PR c++/85847
> +// { dg-do compile { target c++11 } }
> +
> +template <class>
> +int f(int b) { return b; }
> +
> +template <class>
> +void g()
> +{
> +  auto a = new int[f<int>(2), 2];
> +}

Reply via email to