This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ PATCH for c++/85977, array reference size deduction failure


OK.

On Wed, Jun 6, 2018 at 7:28 PM, Marek Polacek <polacek@redhat.com> wrote:
> On Wed, Jun 06, 2018 at 06:22:16PM +0200, Jason Merrill wrote:
>> Right, you want to test conversion to the element type, not the array or
>> init list type.
>
> Indeed.  Please tell me this is the right approach :).
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-06-06  Marek Polacek  <polacek@redhat.com>
>
>         PR c++/85977
>         * pt.c (unify): If ELTTYPE has no deducible template parms, skip
>         deduction from the list elements.
>         (type_unification_real): Check convertibility of list elements.
>
>         * g++.dg/cpp0x/initlist102.C: New test.
>         * g++.dg/cpp0x/initlist103.C: New test.
>         * g++.dg/cpp0x/initlist104.C: New test.
>
> diff --git gcc/cp/pt.c gcc/cp/pt.c
> index 448cd69b722..d8880eb138d 100644
> --- gcc/cp/pt.c
> +++ gcc/cp/pt.c
> @@ -20370,6 +20370,22 @@ type_unification_real (tree tparms,
>             if (check_non_deducible_conversion (parm, arg, strict, flags,
>                                                 explain_p))
>               return 1;
> +
> +           if (BRACE_ENCLOSED_INITIALIZER_P (arg)
> +               && (TREE_CODE (parm) == ARRAY_TYPE || is_std_init_list (parm)))
> +             {
> +               tree elt, elttype;
> +               unsigned int i;
> +
> +               if (TREE_CODE (parm) == ARRAY_TYPE)
> +                 elttype = TREE_TYPE (parm);
> +               else
> +                 elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
> +               FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
> +                 if (check_non_deducible_conversion (elttype, elt, strict,
> +                                                     flags, explain_p))
> +                   return 1;
> +             }
>           }
>
>        /* Now substitute into the default template arguments.  */
> @@ -21404,24 +21420,30 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
>             return unify_success (explain_p);
>         }
>
> -      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
> -       {
> -         int elt_strict = strict;
> +      if (strict != DEDUCE_EXACT
> +         && TYPE_P (elttype)
> +         && !uses_deducible_template_parms (elttype))
> +       /* If ELTTYPE has no deducible template parms, skip deduction from
> +          the list elements.  */;
> +      else
> +       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
> +         {
> +           int elt_strict = strict;
>
> -         if (elt == error_mark_node)
> -           return unify_invalid (explain_p);
> +           if (elt == error_mark_node)
> +             return unify_invalid (explain_p);
>
> -         if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
> -           {
> -             tree type = TREE_TYPE (elt);
> -             if (type == error_mark_node)
> -               return unify_invalid (explain_p);
> -             /* It should only be possible to get here for a call.  */
> -             gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL);
> -             elt_strict |= maybe_adjust_types_for_deduction
> -               (DEDUCE_CALL, &elttype, &type, elt);
> -             elt = type;
> -           }
> +           if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
> +             {
> +               tree type = TREE_TYPE (elt);
> +               if (type == error_mark_node)
> +                 return unify_invalid (explain_p);
> +               /* It should only be possible to get here for a call.  */
> +               gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL);
> +               elt_strict |= maybe_adjust_types_for_deduction
> +                 (DEDUCE_CALL, &elttype, &type, elt);
> +               elt = type;
> +             }
>
>           RECUR_AND_CHECK_FAILURE (tparms, targs, elttype, elt, elt_strict,
>                                    explain_p);
> diff --git gcc/testsuite/g++.dg/cpp0x/initlist102.C gcc/testsuite/g++.dg/cpp0x/initlist102.C
> index e69de29bb2d..e114866292f 100644
> --- gcc/testsuite/g++.dg/cpp0x/initlist102.C
> +++ gcc/testsuite/g++.dg/cpp0x/initlist102.C
> @@ -0,0 +1,39 @@
> +// PR c++/85977, Incorrect handling of array reference size deduction
> +// { dg-do compile { target c++11 } }
> +
> +template <int N>
> +void fn1 (const char (&)[N]) { static_assert (N == 3, "fn1");}
> +
> +template <int N>
> +void fn2 (const short (&)[N]) { static_assert (N == 3, "fn2");}
> +
> +template <int N>
> +void fn3 (const int (&)[N]) { static_assert (N == 3, "fn2");}
> +
> +template <int N>
> +void fn4 (const long (&)[N]) { static_assert (N == 3, "fn4");}
> +
> +template <int N>
> +void fn5 (const unsigned char (&)[N]) { static_assert (N == 3, "fn5");}
> +
> +template <int N>
> +void fn6 (const unsigned short (&)[N]) { static_assert (N == 3, "fn6");}
> +
> +template <int N>
> +void fn7 (const unsigned int (&)[N]) { static_assert (N == 3, "fn7");}
> +
> +template <int N>
> +void fn8 (const unsigned int (&)[N]) { static_assert (N == 3, "fn8");}
> +
> +void
> +bar ()
> +{
> +  fn1 ({1, 2, 3});
> +  fn2 ({1, 2, 3});
> +  fn3 ({1, 2, 3});
> +  fn4 ({1, 2, 3});
> +  fn5 ({1, 2, 3});
> +  fn6 ({1, 2, 3});
> +  fn7 ({1, 2, 3});
> +  fn8 ({1, 2, 3});
> +}
> diff --git gcc/testsuite/g++.dg/cpp0x/initlist103.C gcc/testsuite/g++.dg/cpp0x/initlist103.C
> index e69de29bb2d..0c1923c6ab0 100644
> --- gcc/testsuite/g++.dg/cpp0x/initlist103.C
> +++ gcc/testsuite/g++.dg/cpp0x/initlist103.C
> @@ -0,0 +1,11 @@
> +// PR c++/85977, Incorrect handling of array reference size deduction
> +// { dg-do compile { target c++11 } }
> +
> +template <int N>
> +void fn (const char (&)[N]) { }
> +
> +void
> +bar ()
> +{
> +  fn ({1.2}); // { dg-error "narrowing" }
> +}
> diff --git gcc/testsuite/g++.dg/cpp0x/initlist104.C gcc/testsuite/g++.dg/cpp0x/initlist104.C
> index e69de29bb2d..99487a70607 100644
> --- gcc/testsuite/g++.dg/cpp0x/initlist104.C
> +++ gcc/testsuite/g++.dg/cpp0x/initlist104.C
> @@ -0,0 +1,11 @@
> +// PR c++/85977, Incorrect handling of array reference size deduction
> +// { dg-do compile { target c++11 } }
> +
> +template <typename T, int N>
> +void fn (const T (&)[N]) { static_assert (N == 3, "fn"); }
> +
> +void
> +bar ()
> +{
> +  fn ({1, 2, 3});
> +}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]