diff mbox

[C++] Fix ICE when throwing va_list (PR c++/72809)

Message ID 20160808190912.GO14857@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Aug. 8, 2016, 7:09 p.m. UTC
Hi!

If va_list is one-entry array of structs, those RECORD_TYPEs don't
have TYPE_BINFO.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

I've made the testcase compile instead of run, because while it with the
patch works both on x86_64-linux and i686-linux, not sure if it really
should be well defined - at least in C one can copy va_list only through
va_copy, by throwing it and catching it is copied in some other way.

2016-08-08  Jakub Jelinek  <jakub@redhat.com>

	PR c++/72809
	* rtti.c (get_pseudo_ti_index): Return TK_CLASS_TYPE for
	builtin aggregate types without TYPE_BINFO.

	* g++.dg/eh/stdarg1.C: New test.


	Jakub

Comments

Jason Merrill Aug. 8, 2016, 9:15 p.m. UTC | #1
OK.

On Mon, Aug 8, 2016 at 3:09 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> If va_list is one-entry array of structs, those RECORD_TYPEs don't
> have TYPE_BINFO.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
>
> I've made the testcase compile instead of run, because while it with the
> patch works both on x86_64-linux and i686-linux, not sure if it really
> should be well defined - at least in C one can copy va_list only through
> va_copy, by throwing it and catching it is copied in some other way.
>
> 2016-08-08  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/72809
>         * rtti.c (get_pseudo_ti_index): Return TK_CLASS_TYPE for
>         builtin aggregate types without TYPE_BINFO.
>
>         * g++.dg/eh/stdarg1.C: New test.
>
> --- gcc/cp/rtti.c.jj    2016-04-22 18:21:27.000000000 +0200
> +++ gcc/cp/rtti.c       2016-08-08 16:21:32.937053462 +0200
> @@ -1293,7 +1293,8 @@ get_pseudo_ti_index (tree type)
>           ix = TK_CLASS_TYPE;
>           break;
>         }
> -      else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
> +      else if (!TYPE_BINFO (type)
> +              || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
>         {
>           ix = TK_CLASS_TYPE;
>           break;
> --- gcc/testsuite/g++.dg/eh/stdarg1.C.jj        2016-08-08 16:31:52.553510463 +0200
> +++ gcc/testsuite/g++.dg/eh/stdarg1.C   2016-08-08 16:30:20.000000000 +0200
> @@ -0,0 +1,30 @@
> +// PR c++/72809
> +// { dg-do compile }
> +
> +#include <stdarg.h>
> +
> +int
> +foo (int a, ...)
> +{
> +  va_list ap;
> +  int r = 0;
> +  va_start (ap, a);
> +  try
> +    {
> +      if (a == 1)
> +       throw (ap);
> +    }
> +  catch (va_list b)
> +    {
> +      r = va_arg (b, int);
> +    }
> +  va_end (ap);
> +  return r;
> +}
> +
> +int
> +main ()
> +{
> +  if (foo (0) != 0 || foo (1, 7) != 7)
> +    __builtin_abort ();
> +}
>
>         Jakub
diff mbox

Patch

--- gcc/cp/rtti.c.jj	2016-04-22 18:21:27.000000000 +0200
+++ gcc/cp/rtti.c	2016-08-08 16:21:32.937053462 +0200
@@ -1293,7 +1293,8 @@  get_pseudo_ti_index (tree type)
 	  ix = TK_CLASS_TYPE;
 	  break;
 	}
-      else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
+      else if (!TYPE_BINFO (type)
+	       || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
 	{
 	  ix = TK_CLASS_TYPE;
 	  break;
--- gcc/testsuite/g++.dg/eh/stdarg1.C.jj	2016-08-08 16:31:52.553510463 +0200
+++ gcc/testsuite/g++.dg/eh/stdarg1.C	2016-08-08 16:30:20.000000000 +0200
@@ -0,0 +1,30 @@ 
+// PR c++/72809
+// { dg-do compile }
+
+#include <stdarg.h>
+
+int
+foo (int a, ...)
+{
+  va_list ap;
+  int r = 0;
+  va_start (ap, a);
+  try
+    {
+      if (a == 1)
+	throw (ap);
+    }
+  catch (va_list b)
+    {
+      r = va_arg (b, int);
+    }
+  va_end (ap);
+  return r;
+}
+
+int
+main ()
+{
+  if (foo (0) != 0 || foo (1, 7) != 7)
+    __builtin_abort ();
+}