This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Use tsubst instead of tsubst_copy for VA_ARG_EXPR's second argument (PR c++/47022)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 6 Jan 2011 01:06:48 +0100
- Subject: [C++ PATCH] Use tsubst instead of tsubst_copy for VA_ARG_EXPR's second argument (PR c++/47022)
- References: <20110101182742.GX16156@tyan-ft48-01.lab.bos.redhat.com> <4D24752F.8080809@redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Wed, Jan 05, 2011 at 08:42:07AM -0500, Jason Merrill wrote:
> On 01/01/2011 01:27 PM, Jakub Jelinek wrote:
> >One fix is attached, another possibility (untested) would be to pass through
> >all TYPE_Ps to tsubst in default: for tsubst_copy, another is
> >use tsubst instead of tsubst_copy on VA_ARG_EXPR's second argument in
> >tsubst_copy_and_build (or any combination of those).
>
> The last of those, please.
Here it is, bootstrapped/regtested on x86_64-linux and i686-linux, ok?
2011-01-05 Jakub Jelinek <jakub@redhat.com>
PR c++/47022
* pt.c (tsubst_copy_and_build): Use tsubst instead of tsubst_copy
for the second build_x_va_arg argument.
* g++.dg/template/stdarg1.C: New test.
--- gcc/cp/pt.c.jj 2011-01-03 09:54:01.000000000 +0100
+++ gcc/cp/pt.c 2011-01-05 14:50:22.000000000 +0100
@@ -13239,8 +13239,7 @@ tsubst_copy_and_build (tree t,
case VA_ARG_EXPR:
return build_x_va_arg (RECUR (TREE_OPERAND (t, 0)),
- tsubst_copy (TREE_TYPE (t), args, complain,
- in_decl));
+ tsubst (TREE_TYPE (t), args, complain, in_decl));
case OFFSETOF_EXPR:
return finish_offsetof (RECUR (TREE_OPERAND (t, 0)));
--- gcc/testsuite/g++.dg/template/stdarg1.C.jj 2010-12-31 11:56:29.000000000 +0100
+++ gcc/testsuite/g++.dg/template/stdarg1.C 2010-12-31 11:55:56.000000000 +0100
@@ -0,0 +1,53 @@
+// PR c++/47022
+// { dg-do compile }
+
+#include <cstdarg>
+
+template <typename T>
+void
+f1 (T *p, va_list ap)
+{
+ *p = va_arg (ap, long double);
+ *p += va_arg (ap, double);
+}
+
+template <typename T>
+void
+f2 (T *p, va_list ap)
+{
+ *p = __real__ va_arg (ap, _Complex int);
+ *p += __imag__ va_arg (ap, _Complex double);
+ *p += __imag__ va_arg (ap, _Complex long double);
+}
+
+template <typename T>
+void
+f3 (T *p, va_list ap)
+{
+ *p = va_arg (ap, T);
+}
+
+void
+foo (int x, va_list ap)
+{
+ if (x == 0)
+ {
+ long double ld;
+ f1 (&ld, ap);
+ }
+ else if (x == 1)
+ {
+ int i;
+ f2 (&i, ap);
+ }
+ else if (x == 2)
+ {
+ long double ld;
+ f3 (&ld, ap);
+ }
+ else if (x == 3)
+ {
+ _Complex double cd;
+ f3 (&cd, ap);
+ }
+}
Jakub