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