On Thu, Dec 08, 2016 at 10:07:59PM +0100, Marek Polacek wrote:
> 2016-12-08  Marek Polacek  <pola...@redhat.com>
> 
>       PR middle-end/78716
>       * gimplify.c (gimplify_va_arg_expr): Don't require ADDR_EXPR for
>       Case 1.
> 
>       * g++.dg/other/vararg-5.C: New.
> 
> diff --git gcc/gimplify.c gcc/gimplify.c
> index 8611060..08c4faa 100644
> --- gcc/gimplify.c
> +++ gcc/gimplify.c
> @@ -12642,8 +12642,7 @@ gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
>    if (have_va_type == error_mark_node)
>      return GS_ERROR;
>    have_va_type = targetm.canonical_va_list_type (have_va_type);
> -  if (have_va_type == NULL_TREE
> -      && TREE_CODE (valist) == ADDR_EXPR)
> +  if (have_va_type == NULL_TREE)
>      /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg.  */
>      have_va_type
>        = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));

This assumes that TREE_TYPE (TREE_TYPE (valist)) is meaningful, which
isn't always the case.  So, shall it check instead that
POINTER_TYPE_P (TREE_TYPE (valist))
instead, or do we have any guarantees valist must be a pointer at this
point?

> diff --git gcc/testsuite/g++.dg/other/vararg-5.C 
> gcc/testsuite/g++.dg/other/vararg-5.C
> index e69de29..9327bd6 100644
> --- gcc/testsuite/g++.dg/other/vararg-5.C
> +++ gcc/testsuite/g++.dg/other/vararg-5.C
> @@ -0,0 +1,24 @@
> +// PR middle-end/78716
> +// { dg-do compile }
> +
> +template <typename = int, typename = int, typename = int, typename = int,
> +                typename = int>
> +                struct a;
> +                template <typename> struct b;
> +                template <typename = int, typename d = void> class e : 
> b<d>::c {
> +                  public:
> +                      typedef e f;
> +                        typedef typename b<d>::c g;
> +                          e(__builtin_va_list *s) : g(__builtin_va_arg(*s, 
> int)) {}
> +                };
> +template <> struct b<void> { typedef e<> c; };
> +template <> struct e<> { template <typename h> e(h); };
> +template <typename i> class a<i> : public e<i> {};
> +template <typename i, typename j, typename k, typename l>
> +class a<i, j, k, l> : e<typename a<j>::f> {
> +  public:
> +      template <typename m, typename n, typename o, typename p>
> +       a(a<m, n, o, p>) : a::f(0) {}
> +};
> +template <typename i, typename j, typename k, typename l> a<> r(i, j, k, l);
> +void q() { a<float, float>(r(4, 6, 9, 7)); }
> 
>       Marek

        Jakub

Reply via email to